home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / gmpxx.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-07  |  112.3 KB  |  3,390 lines

  1. /* gmpxx.h -- C++ class wrapper for GMP types.  -*- C++ -*-
  2.  
  3. Copyright 2001, 2002, 2003, 2006, 2008 Free Software Foundation, Inc.
  4.  
  5. This file is part of the GNU MP Library.
  6.  
  7. The GNU MP Library is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU Lesser General Public License as published by
  9. the Free Software Foundation; either version 3 of the License, or (at your
  10. option) any later version.
  11.  
  12. The GNU MP Library is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  15. License for more details.
  16.  
  17. You should have received a copy of the GNU Lesser General Public License
  18. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  19.  
  20. /* the C++ compiler must implement the following features:
  21.    - member templates
  22.    - partial specialization of templates
  23.    - namespace support
  24.    for g++, this means version 2.91 or higher
  25.    for other compilers, I don't know */
  26. #ifdef __GNUC__
  27. #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
  28. #error gmpxx.h requires g++ version 2.91 (egcs 1.1.2) or higher
  29. #endif
  30. #endif
  31.  
  32. #ifndef __GMP_PLUSPLUS__
  33. #define __GMP_PLUSPLUS__
  34.  
  35. #include <iosfwd>
  36.  
  37. #include <cstring>  /* for strlen */
  38. #include <string>
  39. #include <stdexcept>
  40. #include <cfloat>
  41. #include <gmp.h>
  42.  
  43.  
  44. /**************** Function objects ****************/
  45. /* Any evaluation of a __gmp_expr ends up calling one of these functions
  46.    all intermediate functions being inline, the evaluation should optimize
  47.    to a direct call to the relevant function, thus yielding no overhead
  48.    over the C interface. */
  49.  
  50. struct __gmp_unary_plus
  51. {
  52.   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
  53.   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
  54.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
  55. };
  56.  
  57. struct __gmp_unary_minus
  58. {
  59.   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
  60.   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
  61.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
  62. };
  63.  
  64. struct __gmp_unary_com
  65. {
  66.   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
  67. };
  68.  
  69. struct __gmp_binary_plus
  70. {
  71.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  72.   { mpz_add(z, w, v); }
  73.  
  74.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  75.   { mpz_add_ui(z, w, l); }
  76.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  77.   { mpz_add_ui(z, w, l); }
  78.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  79.   {
  80.     if (l >= 0)
  81.       mpz_add_ui(z, w, l);
  82.     else
  83.       mpz_sub_ui(z, w, -l);
  84.   }
  85.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  86.   {
  87.     if (l >= 0)
  88.       mpz_add_ui(z, w, l);
  89.     else
  90.       mpz_sub_ui(z, w, -l);
  91.   }
  92.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  93.   {
  94.     mpz_t temp;
  95.     mpz_init_set_d(temp, d);
  96.     mpz_add(z, w, temp);
  97.     mpz_clear(temp);
  98.   }
  99.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  100.   {
  101.     mpz_t temp;
  102.     mpz_init_set_d(temp, d);
  103.     mpz_add(z, temp, w);
  104.     mpz_clear(temp);
  105.   }
  106.  
  107.   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  108.   { mpq_add(q, r, s); }
  109.  
  110.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  111.   { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
  112.   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  113.   { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
  114.   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  115.   {
  116.     mpq_set(q, r);
  117.     if (l >= 0)
  118.       mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
  119.     else
  120.       mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
  121.   }
  122.   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  123.   {
  124.     mpq_set(q, r);
  125.     if (l >= 0)
  126.       mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
  127.     else
  128.       mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
  129.   }
  130.   static void eval(mpq_ptr q, mpq_srcptr r, double d)
  131.   {
  132.     mpq_t temp;
  133.     mpq_init(temp);
  134.     mpq_set_d(temp, d);
  135.     mpq_add(q, r, temp);
  136.     mpq_clear(temp);
  137.   }
  138.   static void eval(mpq_ptr q, double d, mpq_srcptr r)
  139.   {
  140.     mpq_t temp;
  141.     mpq_init(temp);
  142.     mpq_set_d(temp, d);
  143.     mpq_add(q, temp, r);
  144.     mpq_clear(temp);
  145.   }
  146.  
  147.   static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
  148.   { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
  149.   static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
  150.   { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
  151.  
  152.   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  153.   { mpf_add(f, g, h); }
  154.  
  155.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  156.   { mpf_add_ui(f, g, l); }
  157.   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  158.   { mpf_add_ui(f, g, l); }
  159.   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  160.   {
  161.     if (l >= 0)
  162.       mpf_add_ui(f, g, l);
  163.     else
  164.       mpf_sub_ui(f, g, -l);
  165.   }
  166.   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  167.   {
  168.     if (l >= 0)
  169.       mpf_add_ui(f, g, l);
  170.     else
  171.       mpf_sub_ui(f, g, -l);
  172.   }
  173.   static void eval(mpf_ptr f, mpf_srcptr g, double d)
  174.   {
  175.     mpf_t temp;
  176.     mpf_init2(temp, 8*sizeof(double));
  177.     mpf_set_d(temp, d);
  178.     mpf_add(f, g, temp);
  179.     mpf_clear(temp);
  180.   }
  181.   static void eval(mpf_ptr f, double d, mpf_srcptr g)
  182.   {
  183.     mpf_t temp;
  184.     mpf_init2(temp, 8*sizeof(double));
  185.     mpf_set_d(temp, d);
  186.     mpf_add(f, temp, g);
  187.     mpf_clear(temp);
  188.   }
  189. };
  190.  
  191. struct __gmp_binary_minus
  192. {
  193.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  194.   { mpz_sub(z, w, v); }
  195.  
  196.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  197.   { mpz_sub_ui(z, w, l); }
  198.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  199.   { mpz_ui_sub(z, l, w); }
  200.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  201.   {
  202.     if (l >= 0)
  203.       mpz_sub_ui(z, w, l);
  204.     else
  205.       mpz_add_ui(z, w, -l);
  206.   }
  207.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  208.   {
  209.     if (l >= 0)
  210.       mpz_ui_sub(z, l, w);
  211.     else
  212.       {
  213.         mpz_add_ui(z, w, -l);
  214.         mpz_neg(z, z);
  215.       }
  216.   }
  217.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  218.   {
  219.     mpz_t temp;
  220.     mpz_init_set_d(temp, d);
  221.     mpz_sub(z, w, temp);
  222.     mpz_clear(temp);
  223.   }
  224.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  225.   {
  226.     mpz_t temp;
  227.     mpz_init_set_d(temp, d);
  228.     mpz_sub(z, temp, w);
  229.     mpz_clear(temp);
  230.   }
  231.  
  232.   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  233.   { mpq_sub(q, r, s); }
  234.  
  235.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  236.   { mpq_set(q, r); mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); }
  237.   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  238.   { mpq_neg(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
  239.   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  240.   {
  241.     mpq_set(q, r);
  242.     if (l >= 0)
  243.       mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
  244.     else
  245.       mpz_addmul_ui(mpq_numref(q), mpq_denref(q), -l);
  246.   }
  247.   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  248.   {
  249.     mpq_neg(q, r);
  250.     if (l >= 0)
  251.       mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
  252.     else
  253.       mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
  254.   }
  255.   static void eval(mpq_ptr q, mpq_srcptr r, double d)
  256.   {
  257.     mpq_t temp;
  258.     mpq_init(temp);
  259.     mpq_set_d(temp, d);
  260.     mpq_sub(q, r, temp);
  261.     mpq_clear(temp);
  262.   }
  263.   static void eval(mpq_ptr q, double d, mpq_srcptr r)
  264.   {
  265.     mpq_t temp;
  266.     mpq_init(temp);
  267.     mpq_set_d(temp, d);
  268.     mpq_sub(q, temp, r);
  269.     mpq_clear(temp);
  270.   }
  271.  
  272.   static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
  273.   { mpq_set(q, r); mpz_submul(mpq_numref(q), mpq_denref(q), z); }
  274.   static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
  275.   { mpq_neg(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
  276.  
  277.   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  278.   { mpf_sub(f, g, h); }
  279.  
  280.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  281.   { mpf_sub_ui(f, g, l); }
  282.   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  283.   { mpf_ui_sub(f, l, g); }
  284.   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  285.   {
  286.     if (l >= 0)
  287.       mpf_sub_ui(f, g, l);
  288.     else
  289.       mpf_add_ui(f, g, -l);
  290.   }
  291.   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  292.   {
  293.     if (l >= 0)
  294.       mpf_sub_ui(f, g, l);
  295.     else
  296.       mpf_add_ui(f, g, -l);
  297.     mpf_neg(f, f);
  298.   }
  299.   static void eval(mpf_ptr f, mpf_srcptr g, double d)
  300.   {
  301.     mpf_t temp;
  302.     mpf_init2(temp, 8*sizeof(double));
  303.     mpf_set_d(temp, d);
  304.     mpf_sub(f, g, temp);
  305.     mpf_clear(temp);
  306.   }
  307.   static void eval(mpf_ptr f, double d, mpf_srcptr g)
  308.   {
  309.     mpf_t temp;
  310.     mpf_init2(temp, 8*sizeof(double));
  311.     mpf_set_d(temp, d);
  312.     mpf_sub(f, temp, g);
  313.     mpf_clear(temp);
  314.   }
  315. };
  316.  
  317. struct __gmp_binary_multiplies
  318. {
  319.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  320.   { mpz_mul(z, w, v); }
  321.  
  322.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  323.   { mpz_mul_ui(z, w, l); }
  324.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  325.   { mpz_mul_ui(z, w, l); }
  326.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  327.   { mpz_mul_si (z, w, l); }
  328.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  329.   { mpz_mul_si (z, w, l); }
  330.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  331.   {
  332.     mpz_t temp;
  333.     mpz_init_set_d(temp, d);
  334.     mpz_mul(z, w, temp);
  335.     mpz_clear(temp);
  336.   }
  337.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  338.   {
  339.     mpz_t temp;
  340.     mpz_init_set_d(temp, d);
  341.     mpz_mul(z, temp, w);
  342.     mpz_clear(temp);
  343.   }
  344.  
  345.   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  346.   { mpq_mul(q, r, s); }
  347.  
  348.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  349.   {
  350.     mpq_t temp;
  351.     mpq_init(temp);
  352.     mpq_set_ui(temp, l, 1);
  353.     mpq_mul(q, r, temp);
  354.     mpq_clear(temp);
  355.   }
  356.   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  357.   {
  358.     mpq_t temp;
  359.     mpq_init(temp);
  360.     mpq_set_ui(temp, l, 1);
  361.     mpq_mul(q, temp, r);
  362.     mpq_clear(temp);
  363.   }
  364.   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  365.   {
  366.     mpq_t temp;
  367.     mpq_init(temp);
  368.     mpq_set_si(temp, l, 1);
  369.     mpq_mul(q, r, temp);
  370.     mpq_clear(temp);
  371.   }
  372.   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  373.   {
  374.     mpq_t temp;
  375.     mpq_init(temp);
  376.     mpq_set_si(temp, l, 1);
  377.     mpq_mul(q, temp, r);
  378.     mpq_clear(temp);
  379.   }
  380.   static void eval(mpq_ptr q, mpq_srcptr r, double d)
  381.   {
  382.     mpq_t temp;
  383.     mpq_init(temp);
  384.     mpq_set_d(temp, d);
  385.     mpq_mul(q, r, temp);
  386.     mpq_clear(temp);
  387.   }
  388.   static void eval(mpq_ptr q, double d, mpq_srcptr r)
  389.   {
  390.     mpq_t temp;
  391.     mpq_init(temp);
  392.     mpq_set_d(temp, d);
  393.     mpq_mul(q, temp, r);
  394.     mpq_clear(temp);
  395.   }
  396.  
  397.   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  398.   { mpf_mul(f, g, h); }
  399.  
  400.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  401.   { mpf_mul_ui(f, g, l); }
  402.   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  403.   { mpf_mul_ui(f, g, l); }
  404.   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  405.   {
  406.     if (l >= 0)
  407.       mpf_mul_ui(f, g, l);
  408.     else
  409.       {
  410.     mpf_mul_ui(f, g, -l);
  411.     mpf_neg(f, f);
  412.       }
  413.   }
  414.   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  415.   {
  416.     if (l >= 0)
  417.       mpf_mul_ui(f, g, l);
  418.     else
  419.       {
  420.     mpf_mul_ui(f, g, -l);
  421.     mpf_neg(f, f);
  422.       }
  423.   }
  424.   static void eval(mpf_ptr f, mpf_srcptr g, double d)
  425.   {
  426.     mpf_t temp;
  427.     mpf_init2(temp, 8*sizeof(double));
  428.     mpf_set_d(temp, d);
  429.     mpf_mul(f, g, temp);
  430.     mpf_clear(temp);
  431.   }
  432.   static void eval(mpf_ptr f, double d, mpf_srcptr g)
  433.   {
  434.     mpf_t temp;
  435.     mpf_init2(temp, 8*sizeof(double));
  436.     mpf_set_d(temp, d);
  437.     mpf_mul(f, temp, g);
  438.     mpf_clear(temp);
  439.   }
  440. };
  441.  
  442. struct __gmp_binary_divides
  443. {
  444.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  445.   { mpz_tdiv_q(z, w, v); }
  446.  
  447.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  448.   { mpz_tdiv_q_ui(z, w, l); }
  449.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  450.   {
  451.     if (mpz_sgn(w) >= 0)
  452.       {
  453.     if (mpz_fits_ulong_p(w))
  454.       mpz_set_ui(z, l / mpz_get_ui(w));
  455.     else
  456.       mpz_set_ui(z, 0);
  457.       }
  458.     else
  459.       {
  460.     mpz_neg(z, w);
  461.     if (mpz_fits_ulong_p(z))
  462.       {
  463.         mpz_set_ui(z, l / mpz_get_ui(z));
  464.         mpz_neg(z, z);
  465.       }
  466.     else
  467.       mpz_set_ui(z, 0);
  468.       }
  469.   }
  470.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  471.   {
  472.     if (l >= 0)
  473.       mpz_tdiv_q_ui(z, w, l);
  474.     else
  475.       {
  476.     mpz_tdiv_q_ui(z, w, -l);
  477.     mpz_neg(z, z);
  478.       }
  479.   }
  480.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  481.   {
  482.     if (mpz_fits_slong_p(w))
  483.       mpz_set_si(z, l / mpz_get_si(w));
  484.     else
  485.       {
  486.         /* if w is bigger than a long then the quotient must be zero, unless
  487.            l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
  488.         mpz_set_si (z, (mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? -1 : 0));
  489.       }
  490.   }
  491.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  492.   {
  493.     mpz_t temp;
  494.     mpz_init_set_d(temp, d);
  495.     mpz_tdiv_q(z, w, temp);
  496.     mpz_clear(temp);
  497.   }
  498.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  499.   {
  500.     mpz_t temp;
  501.     mpz_init_set_d(temp, d);
  502.     mpz_tdiv_q(z, temp, w);
  503.     mpz_clear(temp);
  504.   }
  505.  
  506.   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
  507.   { mpq_div(q, r, s); }
  508.  
  509.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  510.   {
  511.     mpq_t temp;
  512.     mpq_init(temp);
  513.     mpq_set_ui(temp, l, 1);
  514.     mpq_div(q, r, temp);
  515.     mpq_clear(temp);
  516.   }
  517.   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
  518.   {
  519.     mpq_t temp;
  520.     mpq_init(temp);
  521.     mpq_set_ui(temp, l, 1);
  522.     mpq_div(q, temp, r);
  523.     mpq_clear(temp);
  524.   }
  525.   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
  526.   {
  527.     mpq_t temp;
  528.     mpq_init(temp);
  529.     mpq_set_si(temp, l, 1);
  530.     mpq_div(q, r, temp);
  531.     mpq_clear(temp);
  532.   }
  533.   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
  534.   {
  535.     mpq_t temp;
  536.     mpq_init(temp);
  537.     mpq_set_si(temp, l, 1);
  538.     mpq_div(q, temp, r);
  539.     mpq_clear(temp);
  540.   }
  541.   static void eval(mpq_ptr q, mpq_srcptr r, double d)
  542.   {
  543.     mpq_t temp;
  544.     mpq_init(temp);
  545.     mpq_set_d(temp, d);
  546.     mpq_div(q, r, temp);
  547.     mpq_clear(temp);
  548.   }
  549.   static void eval(mpq_ptr q, double d, mpq_srcptr r)
  550.   {
  551.     mpq_t temp;
  552.     mpq_init(temp);
  553.     mpq_set_d(temp, d);
  554.     mpq_div(q, temp, r);
  555.     mpq_clear(temp);
  556.   }
  557.  
  558.   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  559.   { mpf_div(f, g, h); }
  560.  
  561.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  562.   { mpf_div_ui(f, g, l); }
  563.   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  564.   { mpf_ui_div(f, l, g); }
  565.   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  566.   {
  567.     if (l >= 0)
  568.       mpf_div_ui(f, g, l);
  569.     else
  570.       {
  571.     mpf_div_ui(f, g, -l);
  572.     mpf_neg(f, f);
  573.       }
  574.   }
  575.   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  576.   {
  577.     if (l >= 0)
  578.       mpf_ui_div(f, l, g);
  579.     else
  580.       {
  581.     mpf_ui_div(f, -l, g);
  582.     mpf_neg(f, f);
  583.       }
  584.   }
  585.   static void eval(mpf_ptr f, mpf_srcptr g, double d)
  586.   {
  587.     mpf_t temp;
  588.     mpf_init2(temp, 8*sizeof(double));
  589.     mpf_set_d(temp, d);
  590.     mpf_div(f, g, temp);
  591.     mpf_clear(temp);
  592.   }
  593.   static void eval(mpf_ptr f, double d, mpf_srcptr g)
  594.   {
  595.     mpf_t temp;
  596.     mpf_init2(temp, 8*sizeof(double));
  597.     mpf_set_d(temp, d);
  598.     mpf_div(f, temp, g);
  599.     mpf_clear(temp);
  600.   }
  601. };
  602.  
  603. struct __gmp_binary_modulus
  604. {
  605.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  606.   { mpz_tdiv_r(z, w, v); }
  607.  
  608.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  609.   { mpz_tdiv_r_ui(z, w, l); }
  610.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  611.   {
  612.     if (mpz_sgn(w) >= 0)
  613.       {
  614.     if (mpz_fits_ulong_p(w))
  615.       mpz_set_ui(z, l % mpz_get_ui(w));
  616.     else
  617.       mpz_set_ui(z, l);
  618.       }
  619.     else
  620.       {
  621.     mpz_neg(z, w);
  622.     if (mpz_fits_ulong_p(z))
  623.       mpz_set_ui(z, l % mpz_get_ui(z));
  624.     else
  625.       mpz_set_ui(z, l);
  626.       }
  627.   }
  628.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  629.   {
  630.     mpz_tdiv_r_ui (z, w, (l >= 0 ? l : -l));
  631.   }
  632.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  633.   {
  634.     if (mpz_fits_slong_p(w))
  635.       mpz_set_si(z, l % mpz_get_si(w));
  636.     else
  637.       {
  638.         /* if w is bigger than a long then the remainder is l unchanged,
  639.            unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
  640.         mpz_set_si (z, mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? 0 : l);
  641.       }
  642.   }
  643.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  644.   {
  645.     mpz_t temp;
  646.     mpz_init_set_d(temp, d);
  647.     mpz_tdiv_r(z, w, temp);
  648.     mpz_clear(temp);
  649.   }
  650.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  651.   {
  652.     mpz_t temp;
  653.     mpz_init_set_d(temp, d);
  654.     mpz_tdiv_r(z, temp, w);
  655.     mpz_clear(temp);
  656.   }
  657. };
  658.  
  659. // Max allocations for plain types when converted to mpz_t
  660. // FIXME: how do we get the proper max "double" exponent?
  661. #define __GMP_DBL_LIMBS (2 + DBL_MAX_EXP / GMP_NUMB_BITS)
  662. #define __GMP_ULI_LIMBS (1 + (8 * sizeof (long) - 1) / GMP_NUMB_BITS)
  663.  
  664. #define __GMPXX_TMP_UI                            \
  665.   mpz_t temp;                                \
  666.   mp_limb_t limbs[__GMP_ULI_LIMBS];                    \
  667.   temp->_mp_d = limbs;                            \
  668.   temp->_mp_alloc = __GMP_ULI_LIMBS;                    \
  669.   mpz_set_ui (temp, l)
  670. #define __GMPXX_TMP_SI                            \
  671.   mpz_t temp;                                \
  672.   mp_limb_t limbs[__GMP_ULI_LIMBS];                    \
  673.   temp->_mp_d = limbs;                            \
  674.   temp->_mp_alloc = __GMP_ULI_LIMBS;                    \
  675.   mpz_set_si (temp, l)
  676. #define __GMPXX_TMP_D                            \
  677.   mpz_t temp;                                \
  678.   mp_limb_t limbs[__GMP_DBL_LIMBS];                    \
  679.   temp->_mp_d = limbs;                            \
  680.   temp->_mp_alloc = __GMP_DBL_LIMBS;                    \
  681.   mpz_set_d (temp, d)
  682.  
  683. struct __gmp_binary_and
  684. {
  685.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  686.   { mpz_and(z, w, v); }
  687.  
  688.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  689.   {  __GMPXX_TMP_UI;   mpz_and (z, w, temp);  }
  690.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  691.   {  __GMPXX_TMP_UI;   mpz_and (z, w, temp);  }
  692.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  693.   {  __GMPXX_TMP_SI;   mpz_and (z, w, temp);  }
  694.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  695.   {  __GMPXX_TMP_SI;   mpz_and (z, w, temp);  }
  696.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  697.   {  __GMPXX_TMP_D;    mpz_and (z, w, temp); }
  698.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  699.   {  __GMPXX_TMP_D;    mpz_and (z, w, temp); }
  700. };
  701.  
  702. struct __gmp_binary_ior
  703. {
  704.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  705.   { mpz_ior(z, w, v); }
  706.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  707.   {  __GMPXX_TMP_UI;   mpz_ior (z, w, temp);  }
  708.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  709.   {  __GMPXX_TMP_UI;   mpz_ior (z, w, temp);  }
  710.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  711.   {  __GMPXX_TMP_SI;   mpz_ior (z, w, temp);  }
  712.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  713.   {  __GMPXX_TMP_SI;   mpz_ior (z, w, temp);  }
  714.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  715.   {  __GMPXX_TMP_D;    mpz_ior (z, w, temp); }
  716.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  717.   {  __GMPXX_TMP_D;    mpz_ior (z, w, temp); }
  718. };
  719.  
  720. struct __gmp_binary_xor
  721. {
  722.   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
  723.   { mpz_xor(z, w, v); }
  724.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  725.   {  __GMPXX_TMP_UI;   mpz_xor (z, w, temp);  }
  726.   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
  727.   {  __GMPXX_TMP_UI;   mpz_xor (z, w, temp);  }
  728.   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
  729.   {  __GMPXX_TMP_SI;   mpz_xor (z, w, temp);  }
  730.   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
  731.   {  __GMPXX_TMP_SI;   mpz_xor (z, w, temp);  }
  732.   static void eval(mpz_ptr z, mpz_srcptr w, double d)
  733.   {  __GMPXX_TMP_D;    mpz_xor (z, w, temp); }
  734.   static void eval(mpz_ptr z, double d, mpz_srcptr w)
  735.   {  __GMPXX_TMP_D;    mpz_xor (z, w, temp); }
  736. };
  737.  
  738. struct __gmp_binary_lshift
  739. {
  740.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  741.   { mpz_mul_2exp(z, w, l); }
  742.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  743.   { mpq_mul_2exp(q, r, l); }
  744.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  745.   { mpf_mul_2exp(f, g, l); }
  746. };
  747.  
  748. struct __gmp_binary_rshift
  749. {
  750.   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
  751.   { mpz_fdiv_q_2exp(z, w, l); }
  752.   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
  753.   { mpq_div_2exp(q, r, l); }
  754.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  755.   { mpf_div_2exp(f, g, l); }
  756. };
  757.  
  758. struct __gmp_binary_equal
  759. {
  760.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
  761.  
  762.   static bool eval(mpz_srcptr z, unsigned long int l)
  763.   { return mpz_cmp_ui(z, l) == 0; }
  764.   static bool eval(unsigned long int l, mpz_srcptr z)
  765.   { return mpz_cmp_ui(z, l) == 0; }
  766.   static bool eval(mpz_srcptr z, signed long int l)
  767.   { return mpz_cmp_si(z, l) == 0; }
  768.   static bool eval(signed long int l, mpz_srcptr z)
  769.   { return mpz_cmp_si(z, l) == 0; }
  770.   static bool eval(mpz_srcptr z, double d)
  771.   { return mpz_cmp_d(z, d) == 0; }
  772.   static bool eval(double d, mpz_srcptr z)
  773.   { return mpz_cmp_d(z, d) == 0; }
  774.  
  775.   static bool eval(mpq_srcptr q, mpq_srcptr r)
  776.   { return mpq_equal(q, r) != 0; }
  777.  
  778.   static bool eval(mpq_srcptr q, unsigned long int l)
  779.   { return mpq_cmp_ui(q, l, 1) == 0; }
  780.   static bool eval(unsigned long int l, mpq_srcptr q)
  781.   { return mpq_cmp_ui(q, l, 1) == 0; }
  782.   static bool eval(mpq_srcptr q, signed long int l)
  783.   { return mpq_cmp_si(q, l, 1) == 0; }
  784.   static bool eval(signed long int l, mpq_srcptr q)
  785.   { return mpq_cmp_si(q, l, 1) == 0; }
  786.   static bool eval(mpq_srcptr q, double d)
  787.   {
  788.     bool b;
  789.     mpq_t temp;
  790.     mpq_init(temp);
  791.     mpq_set_d(temp, d);
  792.     b = (mpq_equal(q, temp) != 0);
  793.     mpq_clear(temp);
  794.     return b;
  795.   }
  796.   static bool eval(double d, mpq_srcptr q)
  797.   {
  798.     bool b;
  799.     mpq_t temp;
  800.     mpq_init(temp);
  801.     mpq_set_d(temp, d);
  802.     b = (mpq_equal(temp, q) != 0);
  803.     mpq_clear(temp);
  804.     return b;
  805.   }
  806.  
  807.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
  808.  
  809.   static bool eval(mpf_srcptr f, unsigned long int l)
  810.   { return mpf_cmp_ui(f, l) == 0; }
  811.   static bool eval(unsigned long int l, mpf_srcptr f)
  812.   { return mpf_cmp_ui(f, l) == 0; }
  813.   static bool eval(mpf_srcptr f, signed long int l)
  814.   { return mpf_cmp_si(f, l) == 0; }
  815.   static bool eval(signed long int l, mpf_srcptr f)
  816.   { return mpf_cmp_si(f, l) == 0; }
  817.   static bool eval(mpf_srcptr f, double d)
  818.   { return mpf_cmp_d(f, d) == 0; }
  819.   static bool eval(double d, mpf_srcptr f)
  820.   { return mpf_cmp_d(f, d) == 0; }
  821. };
  822.  
  823. struct __gmp_binary_not_equal
  824. {
  825.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) != 0; }
  826.  
  827.   static bool eval(mpz_srcptr z, unsigned long int l)
  828.   { return mpz_cmp_ui(z, l) != 0; }
  829.   static bool eval(unsigned long int l, mpz_srcptr z)
  830.   { return mpz_cmp_ui(z, l) != 0; }
  831.   static bool eval(mpz_srcptr z, signed long int l)
  832.   { return mpz_cmp_si(z, l) != 0; }
  833.   static bool eval(signed long int l, mpz_srcptr z)
  834.   { return mpz_cmp_si(z, l) != 0; }
  835.   static bool eval(mpz_srcptr z, double d)
  836.   { return mpz_cmp_d(z, d) != 0; }
  837.   static bool eval(double d, mpz_srcptr z)
  838.   { return mpz_cmp_d(z, d) != 0; }
  839.  
  840.   static bool eval(mpq_srcptr q, mpq_srcptr r)
  841.   { return mpq_equal(q, r) == 0; }
  842.  
  843.   static bool eval(mpq_srcptr q, unsigned long int l)
  844.   { return mpq_cmp_ui(q, l, 1) != 0; }
  845.   static bool eval(unsigned long int l, mpq_srcptr q)
  846.   { return mpq_cmp_ui(q, l, 1) != 0; }
  847.   static bool eval(mpq_srcptr q, signed long int l)
  848.   { return mpq_cmp_si(q, l, 1) != 0; }
  849.   static bool eval(signed long int l, mpq_srcptr q)
  850.   { return mpq_cmp_si(q, l, 1) != 0; }
  851.   static bool eval(mpq_srcptr q, double d)
  852.   {
  853.     bool b;
  854.     mpq_t temp;
  855.     mpq_init(temp);
  856.     mpq_set_d(temp, d);
  857.     b = (mpq_equal(q, temp) == 0);
  858.     mpq_clear(temp);
  859.     return b;
  860.   }
  861.   static bool eval(double d, mpq_srcptr q)
  862.   {
  863.     bool b;
  864.     mpq_t temp;
  865.     mpq_init(temp);
  866.     mpq_set_d(temp, d);
  867.     b = (mpq_equal(temp, q) == 0);
  868.     mpq_clear(temp);
  869.     return b;
  870.   }
  871.  
  872.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) != 0; }
  873.  
  874.   static bool eval(mpf_srcptr f, unsigned long int l)
  875.   { return mpf_cmp_ui(f, l) != 0; }
  876.   static bool eval(unsigned long int l, mpf_srcptr f)
  877.   { return mpf_cmp_ui(f, l) != 0; }
  878.   static bool eval(mpf_srcptr f, signed long int l)
  879.   { return mpf_cmp_si(f, l) != 0; }
  880.   static bool eval(signed long int l, mpf_srcptr f)
  881.   { return mpf_cmp_si(f, l) != 0; }
  882.   static bool eval(mpf_srcptr f, double d)
  883.   { return mpf_cmp_d(f, d) != 0; }
  884.   static bool eval(double d, mpf_srcptr f)
  885.   { return mpf_cmp_d(f, d) != 0; }
  886. };
  887.  
  888. struct __gmp_binary_less
  889. {
  890.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
  891.  
  892.   static bool eval(mpz_srcptr z, unsigned long int l)
  893.   { return mpz_cmp_ui(z, l) < 0; }
  894.   static bool eval(unsigned long int l, mpz_srcptr z)
  895.   { return mpz_cmp_ui(z, l) > 0; }
  896.   static bool eval(mpz_srcptr z, signed long int l)
  897.   { return mpz_cmp_si(z, l) < 0; }
  898.   static bool eval(signed long int l, mpz_srcptr z)
  899.   { return mpz_cmp_si(z, l) > 0; }
  900.   static bool eval(mpz_srcptr z, double d)
  901.   { return mpz_cmp_d(z, d) < 0; }
  902.   static bool eval(double d, mpz_srcptr z)
  903.   { return mpz_cmp_d(z, d) > 0; }
  904.  
  905.   static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
  906.  
  907.   static bool eval(mpq_srcptr q, unsigned long int l)
  908.   { return mpq_cmp_ui(q, l, 1) < 0; }
  909.   static bool eval(unsigned long int l, mpq_srcptr q)
  910.   { return mpq_cmp_ui(q, l, 1) > 0; }
  911.   static bool eval(mpq_srcptr q, signed long int l)
  912.   { return mpq_cmp_si(q, l, 1) < 0; }
  913.   static bool eval(signed long int l, mpq_srcptr q)
  914.   { return mpq_cmp_si(q, l, 1) > 0; }
  915.   static bool eval(mpq_srcptr q, double d)
  916.   {
  917.     bool b;
  918.     mpq_t temp;
  919.     mpq_init(temp);
  920.     mpq_set_d(temp, d);
  921.     b = (mpq_cmp(q, temp) < 0);
  922.     mpq_clear(temp);
  923.     return b;
  924.   }
  925.   static bool eval(double d, mpq_srcptr q)
  926.   {
  927.     bool b;
  928.     mpq_t temp;
  929.     mpq_init(temp);
  930.     mpq_set_d(temp, d);
  931.     b = (mpq_cmp(temp, q) < 0);
  932.     mpq_clear(temp);
  933.     return b;
  934.   }
  935.  
  936.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
  937.  
  938.   static bool eval(mpf_srcptr f, unsigned long int l)
  939.   { return mpf_cmp_ui(f, l) < 0; }
  940.   static bool eval(unsigned long int l, mpf_srcptr f)
  941.   { return mpf_cmp_ui(f, l) > 0; }
  942.   static bool eval(mpf_srcptr f, signed long int l)
  943.   { return mpf_cmp_si(f, l) < 0; }
  944.   static bool eval(signed long int l, mpf_srcptr f)
  945.   { return mpf_cmp_si(f, l) > 0; }
  946.   static bool eval(mpf_srcptr f, double d)
  947.   { return mpf_cmp_d(f, d) < 0; }
  948.   static bool eval(double d, mpf_srcptr f)
  949.   { return mpf_cmp_d(f, d) > 0; }
  950. };
  951.  
  952. struct __gmp_binary_less_equal
  953. {
  954.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) <= 0; }
  955.  
  956.   static bool eval(mpz_srcptr z, unsigned long int l)
  957.   { return mpz_cmp_ui(z, l) <= 0; }
  958.   static bool eval(unsigned long int l, mpz_srcptr z)
  959.   { return mpz_cmp_ui(z, l) >= 0; }
  960.   static bool eval(mpz_srcptr z, signed long int l)
  961.   { return mpz_cmp_si(z, l) <= 0; }
  962.   static bool eval(signed long int l, mpz_srcptr z)
  963.   { return mpz_cmp_si(z, l) >= 0; }
  964.   static bool eval(mpz_srcptr z, double d)
  965.   { return mpz_cmp_d(z, d) <= 0; }
  966.   static bool eval(double d, mpz_srcptr z)
  967.   { return mpz_cmp_d(z, d) >= 0; }
  968.  
  969.   static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) <= 0; }
  970.  
  971.   static bool eval(mpq_srcptr q, unsigned long int l)
  972.   { return mpq_cmp_ui(q, l, 1) <= 0; }
  973.   static bool eval(unsigned long int l, mpq_srcptr q)
  974.   { return mpq_cmp_ui(q, l, 1) >= 0; }
  975.   static bool eval(mpq_srcptr q, signed long int l)
  976.   { return mpq_cmp_si(q, l, 1) <= 0; }
  977.   static bool eval(signed long int l, mpq_srcptr q)
  978.   { return mpq_cmp_si(q, l, 1) >= 0; }
  979.   static bool eval(mpq_srcptr q, double d)
  980.   {
  981.     bool b;
  982.     mpq_t temp;
  983.     mpq_init(temp);
  984.     mpq_set_d(temp, d);
  985.     b = (mpq_cmp(q, temp) <= 0);
  986.     mpq_clear(temp);
  987.     return b;
  988.   }
  989.   static bool eval(double d, mpq_srcptr q)
  990.   {
  991.     bool b;
  992.     mpq_t temp;
  993.     mpq_init(temp);
  994.     mpq_set_d(temp, d);
  995.     b = (mpq_cmp(temp, q) <= 0);
  996.     mpq_clear(temp);
  997.     return b;
  998.   }
  999.  
  1000.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) <= 0; }
  1001.  
  1002.   static bool eval(mpf_srcptr f, unsigned long int l)
  1003.   { return mpf_cmp_ui(f, l) <= 0; }
  1004.   static bool eval(unsigned long int l, mpf_srcptr f)
  1005.   { return mpf_cmp_ui(f, l) >= 0; }
  1006.   static bool eval(mpf_srcptr f, signed long int l)
  1007.   { return mpf_cmp_si(f, l) <= 0; }
  1008.   static bool eval(signed long int l, mpf_srcptr f)
  1009.   { return mpf_cmp_si(f, l) >= 0; }
  1010.   static bool eval(mpf_srcptr f, double d)
  1011.   { return mpf_cmp_d(f, d) <= 0; }
  1012.   static bool eval(double d, mpf_srcptr f)
  1013.   { return mpf_cmp_d(f, d) >= 0; }
  1014. };
  1015.  
  1016. struct __gmp_binary_greater
  1017. {
  1018.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; }
  1019.  
  1020.   static bool eval(mpz_srcptr z, unsigned long int l)
  1021.   { return mpz_cmp_ui(z, l) > 0; }
  1022.   static bool eval(unsigned long int l, mpz_srcptr z)
  1023.   { return mpz_cmp_ui(z, l) < 0; }
  1024.   static bool eval(mpz_srcptr z, signed long int l)
  1025.   { return mpz_cmp_si(z, l) > 0; }
  1026.   static bool eval(signed long int l, mpz_srcptr z)
  1027.   { return mpz_cmp_si(z, l) < 0; }
  1028.   static bool eval(mpz_srcptr z, double d)
  1029.   { return mpz_cmp_d(z, d) > 0; }
  1030.   static bool eval(double d, mpz_srcptr z)
  1031.   { return mpz_cmp_d(z, d) < 0; }
  1032.  
  1033.   static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; }
  1034.  
  1035.   static bool eval(mpq_srcptr q, unsigned long int l)
  1036.   { return mpq_cmp_ui(q, l, 1) > 0; }
  1037.   static bool eval(unsigned long int l, mpq_srcptr q)
  1038.   { return mpq_cmp_ui(q, l, 1) < 0; }
  1039.   static bool eval(mpq_srcptr q, signed long int l)
  1040.   { return mpq_cmp_si(q, l, 1) > 0; }
  1041.   static bool eval(signed long int l, mpq_srcptr q)
  1042.   { return mpq_cmp_si(q, l, 1) < 0; }
  1043.   static bool eval(mpq_srcptr q, double d)
  1044.   {
  1045.     bool b;
  1046.     mpq_t temp;
  1047.     mpq_init(temp);
  1048.     mpq_set_d(temp, d);
  1049.     b = (mpq_cmp(q, temp) > 0);
  1050.     mpq_clear(temp);
  1051.     return b;
  1052.   }
  1053.   static bool eval(double d, mpq_srcptr q)
  1054.   {
  1055.     bool b;
  1056.     mpq_t temp;
  1057.     mpq_init(temp);
  1058.     mpq_set_d(temp, d);
  1059.     b = (mpq_cmp(temp, q) > 0);
  1060.     mpq_clear(temp);
  1061.     return b;
  1062.   }
  1063.  
  1064.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; }
  1065.  
  1066.   static bool eval(mpf_srcptr f, unsigned long int l)
  1067.   { return mpf_cmp_ui(f, l) > 0; }
  1068.   static bool eval(unsigned long int l, mpf_srcptr f)
  1069.   { return mpf_cmp_ui(f, l) < 0; }
  1070.   static bool eval(mpf_srcptr f, signed long int l)
  1071.   { return mpf_cmp_si(f, l) > 0; }
  1072.   static bool eval(signed long int l, mpf_srcptr f)
  1073.   { return mpf_cmp_si(f, l) < 0; }
  1074.   static bool eval(mpf_srcptr f, double d)
  1075.   { return mpf_cmp_d(f, d) > 0; }
  1076.   static bool eval(double d, mpf_srcptr f)
  1077.   { return mpf_cmp_d(f, d) < 0; }
  1078. };
  1079.  
  1080. struct __gmp_binary_greater_equal
  1081. {
  1082.   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) >= 0; }
  1083.  
  1084.   static bool eval(mpz_srcptr z, unsigned long int l)
  1085.   { return mpz_cmp_ui(z, l) >= 0; }
  1086.   static bool eval(unsigned long int l, mpz_srcptr z)
  1087.   { return mpz_cmp_ui(z, l) <= 0; }
  1088.   static bool eval(mpz_srcptr z, signed long int l)
  1089.   { return mpz_cmp_si(z, l) >= 0; }
  1090.   static bool eval(signed long int l, mpz_srcptr z)
  1091.   { return mpz_cmp_si(z, l) <= 0; }
  1092.   static bool eval(mpz_srcptr z, double d)
  1093.   { return mpz_cmp_d(z, d) >= 0; }
  1094.   static bool eval(double d, mpz_srcptr z)
  1095.   { return mpz_cmp_d(z, d) <= 0; }
  1096.  
  1097.   static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) >= 0; }
  1098.  
  1099.   static bool eval(mpq_srcptr q, unsigned long int l)
  1100.   { return mpq_cmp_ui(q, l, 1) >= 0; }
  1101.   static bool eval(unsigned long int l, mpq_srcptr q)
  1102.   { return mpq_cmp_ui(q, l, 1) <= 0; }
  1103.   static bool eval(mpq_srcptr q, signed long int l)
  1104.   { return mpq_cmp_si(q, l, 1) >= 0; }
  1105.   static bool eval(signed long int l, mpq_srcptr q)
  1106.   { return mpq_cmp_si(q, l, 1) <= 0; }
  1107.   static bool eval(mpq_srcptr q, double d)
  1108.   {
  1109.     bool b;
  1110.     mpq_t temp;
  1111.     mpq_init(temp);
  1112.     mpq_set_d(temp, d);
  1113.     b = (mpq_cmp(q, temp) >= 0);
  1114.     mpq_clear(temp);
  1115.     return b;
  1116.   }
  1117.   static bool eval(double d, mpq_srcptr q)
  1118.   {
  1119.     bool b;
  1120.     mpq_t temp;
  1121.     mpq_init(temp);
  1122.     mpq_set_d(temp, d);
  1123.     b = (mpq_cmp(temp, q) >= 0);
  1124.     mpq_clear(temp);
  1125.     return b;
  1126.   }
  1127.  
  1128.   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) >= 0; }
  1129.  
  1130.   static bool eval(mpf_srcptr f, unsigned long int l)
  1131.   { return mpf_cmp_ui(f, l) >= 0; }
  1132.   static bool eval(unsigned long int l, mpf_srcptr f)
  1133.   { return mpf_cmp_ui(f, l) <= 0; }
  1134.   static bool eval(mpf_srcptr f, signed long int l)
  1135.   { return mpf_cmp_si(f, l) >= 0; }
  1136.   static bool eval(signed long int l, mpf_srcptr f)
  1137.   { return mpf_cmp_si(f, l) <= 0; }
  1138.   static bool eval(mpf_srcptr f, double d)
  1139.   { return mpf_cmp_d(f, d) >= 0; }
  1140.   static bool eval(double d, mpf_srcptr f)
  1141.   { return mpf_cmp_d(f, d) <= 0; }
  1142. };
  1143.  
  1144. struct __gmp_unary_increment
  1145. {
  1146.   static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
  1147.   static void eval(mpq_ptr q)
  1148.   { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
  1149.   static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
  1150. };
  1151.  
  1152. struct __gmp_unary_decrement
  1153. {
  1154.   static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
  1155.   static void eval(mpq_ptr q)
  1156.   { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
  1157.   static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
  1158. };
  1159.  
  1160. struct __gmp_abs_function
  1161. {
  1162.   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
  1163.   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
  1164.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
  1165. };
  1166.  
  1167. struct __gmp_trunc_function
  1168. {
  1169.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
  1170. };
  1171.  
  1172. struct __gmp_floor_function
  1173. {
  1174.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
  1175. };
  1176.  
  1177. struct __gmp_ceil_function
  1178. {
  1179.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
  1180. };
  1181.  
  1182. struct __gmp_sqrt_function
  1183. {
  1184.   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
  1185.   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
  1186. };
  1187.  
  1188. struct __gmp_hypot_function
  1189. {
  1190.   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
  1191.   {
  1192.     mpf_t temp;
  1193.     mpf_init2(temp, mpf_get_prec(f));
  1194.     mpf_mul(temp, g, g);
  1195.     mpf_mul(f, h, h);
  1196.     mpf_add(f, f, temp);
  1197.     mpf_sqrt(f, f);
  1198.     mpf_clear(temp);
  1199.   }
  1200.  
  1201.   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
  1202.   {
  1203.     mpf_t temp;
  1204.     mpf_init2(temp, mpf_get_prec(f));
  1205.     mpf_mul(temp, g, g);
  1206.     mpf_set_ui(f, l);
  1207.     mpf_mul(f, f, f);
  1208.     mpf_add(f, f, temp);
  1209.     mpf_sqrt(f, f);
  1210.     mpf_clear(temp);
  1211.   }
  1212.   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
  1213.   {
  1214.     mpf_t temp;
  1215.     mpf_init2(temp, mpf_get_prec(f));
  1216.     mpf_mul(temp, g, g);
  1217.     mpf_set_ui(f, l);
  1218.     mpf_mul(f, f, f);
  1219.     mpf_add(f, f, temp);
  1220.     mpf_sqrt(f, f);
  1221.     mpf_clear(temp);
  1222.   }
  1223.   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
  1224.   {
  1225.     mpf_t temp;
  1226.     mpf_init2(temp, mpf_get_prec(f));
  1227.     mpf_mul(temp, g, g);
  1228.     mpf_set_si(f, l);
  1229.     mpf_mul(f, f, f);
  1230.     mpf_add(f, f, temp);
  1231.     mpf_sqrt(f, f);
  1232.     mpf_clear(temp);
  1233.   }
  1234.   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
  1235.   {
  1236.     mpf_t temp;
  1237.     mpf_init2(temp, mpf_get_prec(f));
  1238.     mpf_mul(temp, g, g);
  1239.     mpf_set_si(f, l);
  1240.     mpf_mul(f, f, f);
  1241.     mpf_add(f, f, temp);
  1242.     mpf_sqrt(f, f);
  1243.     mpf_clear(temp);
  1244.   }
  1245.   static void eval(mpf_ptr f, mpf_srcptr g, double d)
  1246.   {
  1247.     mpf_t temp;
  1248.     mpf_init2(temp, mpf_get_prec(f));
  1249.     mpf_mul(temp, g, g);
  1250.     mpf_set_d(f, d);
  1251.     mpf_mul(f, f, f);
  1252.     mpf_add(f, f, temp);
  1253.     mpf_sqrt(f, f);
  1254.     mpf_clear(temp);
  1255.   }
  1256.   static void eval(mpf_ptr f, double d, mpf_srcptr g)
  1257.   {
  1258.     mpf_t temp;
  1259.     mpf_init2(temp, mpf_get_prec(f));
  1260.     mpf_mul(temp, g, g);
  1261.     mpf_set_d(f, d);
  1262.     mpf_mul(f, f, f);
  1263.     mpf_add(f, f, temp);
  1264.     mpf_sqrt(f, f);
  1265.     mpf_clear(temp);
  1266.   }
  1267. };
  1268.  
  1269. struct __gmp_sgn_function
  1270. {
  1271.   static int eval(mpz_srcptr z) { return mpz_sgn(z); }
  1272.   static int eval(mpq_srcptr q) { return mpq_sgn(q); }
  1273.   static int eval(mpf_srcptr f) { return mpf_sgn(f); }
  1274. };
  1275.  
  1276. struct __gmp_cmp_function
  1277. {
  1278.   static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
  1279.  
  1280.   static int eval(mpz_srcptr z, unsigned long int l)
  1281.   { return mpz_cmp_ui(z, l); }
  1282.   static int eval(unsigned long int l, mpz_srcptr z)
  1283.   { return -mpz_cmp_ui(z, l); }
  1284.   static int eval(mpz_srcptr z, signed long int l)
  1285.   { return mpz_cmp_si(z, l); }
  1286.   static int eval(signed long int l, mpz_srcptr z)
  1287.   { return -mpz_cmp_si(z, l); }
  1288.   static int eval(mpz_srcptr z, double d)
  1289.   { return mpz_cmp_d(z, d); }
  1290.   static int eval(double d, mpz_srcptr z)
  1291.   { return -mpz_cmp_d(z, d); }
  1292.  
  1293.   static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
  1294.  
  1295.   static int eval(mpq_srcptr q, unsigned long int l)
  1296.   { return mpq_cmp_ui(q, l, 1); }
  1297.   static int eval(unsigned long int l, mpq_srcptr q)
  1298.   { return -mpq_cmp_ui(q, l, 1); }
  1299.   static int eval(mpq_srcptr q, signed long int l)
  1300.   { return mpq_cmp_si(q, l, 1); }
  1301.   static int eval(signed long int l, mpq_srcptr q)
  1302.   { return -mpq_cmp_si(q, l, 1); }
  1303.   static int eval(mpq_srcptr q, double d)
  1304.   {
  1305.     int i;
  1306.     mpq_t temp;
  1307.     mpq_init(temp);
  1308.     mpq_set_d(temp, d);
  1309.     i = mpq_cmp(q, temp);
  1310.     mpq_clear(temp);
  1311.     return i;
  1312.   }
  1313.   static int eval(double d, mpq_srcptr q)
  1314.   {
  1315.     int i;
  1316.     mpq_t temp;
  1317.     mpq_init(temp);
  1318.     mpq_set_d(temp, d);
  1319.     i = mpq_cmp(temp, q);
  1320.     mpq_clear(temp);
  1321.     return i;
  1322.   }
  1323.  
  1324.   static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
  1325.  
  1326.   static int eval(mpf_srcptr f, unsigned long int l)
  1327.   { return mpf_cmp_ui(f, l); }
  1328.   static int eval(unsigned long int l, mpf_srcptr f)
  1329.   { return -mpf_cmp_ui(f, l); }
  1330.   static int eval(mpf_srcptr f, signed long int l)
  1331.   { return mpf_cmp_si(f, l); }
  1332.   static int eval(signed long int l, mpf_srcptr f)
  1333.   { return -mpf_cmp_si(f, l); }
  1334.   static int eval(mpf_srcptr f, double d)
  1335.   { return mpf_cmp_d(f, d); }
  1336.   static int eval(double d, mpf_srcptr f)
  1337.   { return -mpf_cmp_d(f, d); }
  1338. };
  1339.  
  1340. struct __gmp_rand_function
  1341. {
  1342.   static void eval(mpz_ptr z, gmp_randstate_t s, unsigned long int l)
  1343.   { mpz_urandomb(z, s, l); }
  1344.   static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
  1345.   { mpz_urandomm(z, s, w); }
  1346.   static void eval(mpf_ptr f, gmp_randstate_t s, unsigned long int prec)
  1347.   { mpf_urandomb(f, s, prec); }
  1348. };
  1349.  
  1350.  
  1351. /**************** Auxiliary classes ****************/
  1352.  
  1353. /* this is much the same as gmp_allocated_string in gmp-impl.h
  1354.    since gmp-impl.h is not publicly available, I redefine it here
  1355.    I use a different name to avoid possible clashes */
  1356.  
  1357. extern "C" {
  1358.   typedef void (*__gmp_freefunc_t) (void *, size_t);
  1359. }
  1360. struct __gmp_alloc_cstring
  1361. {
  1362.   char *str;
  1363.   __gmp_alloc_cstring(char *s) { str = s; }
  1364.   ~__gmp_alloc_cstring()
  1365.   {
  1366.     __gmp_freefunc_t freefunc;
  1367.     mp_get_memory_functions (NULL, NULL, &freefunc);
  1368.     (*freefunc) (str, std::strlen(str)+1);
  1369.   }
  1370. };
  1371.  
  1372.  
  1373. // general expression template class
  1374. template <class T, class U>
  1375. class __gmp_expr;
  1376.  
  1377.  
  1378. // templates for resolving expression types
  1379. template <class T>
  1380. struct __gmp_resolve_ref
  1381. {
  1382.   typedef T ref_type;
  1383. };
  1384.  
  1385. template <class T, class U>
  1386. struct __gmp_resolve_ref<__gmp_expr<T, U> >
  1387. {
  1388.   typedef const __gmp_expr<T, U> & ref_type;
  1389. };
  1390.  
  1391.  
  1392. template <class T, class U = T>
  1393. struct __gmp_resolve_expr;
  1394.  
  1395. template <>
  1396. struct __gmp_resolve_expr<mpz_t>
  1397. {
  1398.   typedef mpz_t value_type;
  1399.   typedef mpz_ptr ptr_type;
  1400. };
  1401.  
  1402. template <>
  1403. struct __gmp_resolve_expr<mpq_t>
  1404. {
  1405.   typedef mpq_t value_type;
  1406.   typedef mpq_ptr ptr_type;
  1407. };
  1408.  
  1409. template <>
  1410. struct __gmp_resolve_expr<mpf_t>
  1411. {
  1412.   typedef mpf_t value_type;
  1413.   typedef mpf_ptr ptr_type;
  1414. };
  1415.  
  1416. template <>
  1417. struct __gmp_resolve_expr<mpz_t, mpq_t>
  1418. {
  1419.   typedef mpq_t value_type;
  1420. };
  1421.  
  1422. template <>
  1423. struct __gmp_resolve_expr<mpq_t, mpz_t>
  1424. {
  1425.   typedef mpq_t value_type;
  1426. };
  1427.  
  1428. template <>
  1429. struct __gmp_resolve_expr<mpz_t, mpf_t>
  1430. {
  1431.   typedef mpf_t value_type;
  1432. };
  1433.  
  1434. template <>
  1435. struct __gmp_resolve_expr<mpf_t, mpz_t>
  1436. {
  1437.   typedef mpf_t value_type;
  1438. };
  1439.  
  1440. template <>
  1441. struct __gmp_resolve_expr<mpq_t, mpf_t>
  1442. {
  1443.   typedef mpf_t value_type;
  1444. };
  1445.  
  1446. template <>
  1447. struct __gmp_resolve_expr<mpf_t, mpq_t>
  1448. {
  1449.   typedef mpf_t value_type;
  1450. };
  1451.  
  1452.  
  1453.  
  1454. template <class T, class U, class V>
  1455. struct __gmp_resolve_temp
  1456. {
  1457.   typedef __gmp_expr<T, T> temp_type;
  1458. };
  1459.  
  1460. template <class T>
  1461. struct __gmp_resolve_temp<T, T, T>
  1462. {
  1463.   typedef const __gmp_expr<T, T> & temp_type;
  1464. };
  1465.  
  1466.  
  1467. // classes for evaluating unary and binary expressions
  1468. template <class T, class Op>
  1469. struct __gmp_unary_expr
  1470. {
  1471.   const T &val;
  1472.  
  1473.   __gmp_unary_expr(const T &v) : val(v) { }
  1474. private:
  1475.   __gmp_unary_expr();
  1476. };
  1477.  
  1478. template <class T, class U, class Op>
  1479. struct __gmp_binary_expr
  1480. {
  1481.   typename __gmp_resolve_ref<T>::ref_type val1;
  1482.   typename __gmp_resolve_ref<U>::ref_type val2;
  1483.  
  1484.   __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
  1485. private:
  1486.   __gmp_binary_expr();
  1487. };
  1488.  
  1489.  
  1490. // functions for evaluating expressions
  1491. template <class T, class U>
  1492. void __gmp_set_expr(mpz_ptr, const __gmp_expr<T, U> &);
  1493. template <class T, class U>
  1494. void __gmp_set_expr(mpq_ptr, const __gmp_expr<T, U> &);
  1495. template <class T, class U>
  1496. void __gmp_set_expr(mpf_ptr, const __gmp_expr<T, U> &);
  1497.  
  1498.  
  1499. /**************** Macros for in-class declarations ****************/
  1500. /* This is just repetitive code that is easier to maintain if it's written
  1501.    only once */
  1502.  
  1503. #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun)                         \
  1504.   template <class T, class U>                                         \
  1505.   __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
  1506.  
  1507. #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
  1508.   __gmp_expr & fun(signed char);              \
  1509.   __gmp_expr & fun(unsigned char);            \
  1510.   __gmp_expr & fun(signed int);               \
  1511.   __gmp_expr & fun(unsigned int);             \
  1512.   __gmp_expr & fun(signed short int);         \
  1513.   __gmp_expr & fun(unsigned short int);       \
  1514.   __gmp_expr & fun(signed long int);          \
  1515.   __gmp_expr & fun(unsigned long int);        \
  1516.   __gmp_expr & fun(float);                    \
  1517.   __gmp_expr & fun(double);                   \
  1518.   __gmp_expr & fun(long double);
  1519.  
  1520. #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
  1521. __GMPP_DECLARE_COMPOUND_OPERATOR(fun)        \
  1522. __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
  1523.  
  1524. #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
  1525.   __gmp_expr & fun(unsigned long int);
  1526.  
  1527. #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
  1528.   inline __gmp_expr & fun();                  \
  1529.   inline __gmp_expr fun(int);
  1530.  
  1531.  
  1532. /**************** mpz_class -- wrapper for mpz_t ****************/
  1533.  
  1534. template <>
  1535. class __gmp_expr<mpz_t, mpz_t>
  1536. {
  1537. private:
  1538.   typedef mpz_t value_type;
  1539.   value_type mp;
  1540. public:
  1541.   unsigned long int get_prec() const { return mpf_get_default_prec(); }
  1542.  
  1543.   // constructors and destructor
  1544.   __gmp_expr() { mpz_init(mp); }
  1545.  
  1546.   __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
  1547.   template <class T, class U>
  1548.   __gmp_expr(const __gmp_expr<T, U> &expr)
  1549.   { mpz_init(mp); __gmp_set_expr(mp, expr); }
  1550.  
  1551.   __gmp_expr(signed char c) { mpz_init_set_si(mp, c); }
  1552.   __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); }
  1553.  
  1554.   __gmp_expr(signed int i) { mpz_init_set_si(mp, i); }
  1555.   __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); }
  1556.  
  1557.   __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); }
  1558.   __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); }
  1559.  
  1560.   __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); }
  1561.   __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); }
  1562.  
  1563.   __gmp_expr(float f) { mpz_init_set_d(mp, f); }
  1564.   __gmp_expr(double d) { mpz_init_set_d(mp, d); }
  1565.   // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); }
  1566.  
  1567.   explicit __gmp_expr(const char *s)
  1568.   {
  1569.     if (mpz_init_set_str (mp, s, 0) != 0)
  1570.       {
  1571.         mpz_clear (mp);
  1572.         throw std::invalid_argument ("mpz_set_str");
  1573.       }
  1574.   }
  1575.   __gmp_expr(const char *s, int base)
  1576.   {
  1577.     if (mpz_init_set_str (mp, s, base) != 0)
  1578.       {
  1579.         mpz_clear (mp);
  1580.         throw std::invalid_argument ("mpz_set_str");
  1581.       }
  1582.   }
  1583.   explicit __gmp_expr(const std::string &s)
  1584.   {
  1585.     if (mpz_init_set_str (mp, s.c_str(), 0) != 0)
  1586.       {
  1587.         mpz_clear (mp);
  1588.         throw std::invalid_argument ("mpz_set_str");
  1589.       }
  1590.   }
  1591.   __gmp_expr(const std::string &s, int base)
  1592.   {
  1593.     if (mpz_init_set_str(mp, s.c_str(), base) != 0)
  1594.       {
  1595.         mpz_clear (mp);
  1596.         throw std::invalid_argument ("mpz_set_str");
  1597.       }
  1598.   }
  1599.  
  1600.   explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
  1601.  
  1602.   ~__gmp_expr() { mpz_clear(mp); }
  1603.  
  1604.   // assignment operators
  1605.   __gmp_expr & operator=(const __gmp_expr &z)
  1606.   { mpz_set(mp, z.mp); return *this; }
  1607.   template <class T, class U>
  1608.   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1609.   { __gmp_set_expr(mp, expr); return *this; }
  1610.  
  1611.   __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; }
  1612.   __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; }
  1613.  
  1614.   __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; }
  1615.   __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; }
  1616.  
  1617.   __gmp_expr & operator=(signed short int s)
  1618.   { mpz_set_si(mp, s); return *this; }
  1619.   __gmp_expr & operator=(unsigned short int s)
  1620.   { mpz_set_ui(mp, s); return *this; }
  1621.  
  1622.   __gmp_expr & operator=(signed long int l)
  1623.   { mpz_set_si(mp, l); return *this; }
  1624.   __gmp_expr & operator=(unsigned long int l)
  1625.   { mpz_set_ui(mp, l); return *this; }
  1626.  
  1627.   __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; }
  1628.   __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; }
  1629.   // __gmp_expr & operator=(long double ld)
  1630.   // { mpz_set_ld(mp, ld); return *this; }
  1631.  
  1632.   __gmp_expr & operator=(const char *s)
  1633.   {
  1634.     if (mpz_set_str (mp, s, 0) != 0)
  1635.       throw std::invalid_argument ("mpz_set_str");
  1636.     return *this;
  1637.   }
  1638.   __gmp_expr & operator=(const std::string &s)
  1639.   {
  1640.     if (mpz_set_str(mp, s.c_str(), 0) != 0)
  1641.       throw std::invalid_argument ("mpz_set_str");
  1642.     return *this;
  1643.   }
  1644.  
  1645.   // string input/output functions
  1646.   int set_str(const char *s, int base)
  1647.   { return mpz_set_str(mp, s, base); }
  1648.   int set_str(const std::string &s, int base)
  1649.   { return mpz_set_str(mp, s.c_str(), base); }
  1650.   std::string get_str(int base = 10) const
  1651.   {
  1652.     __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
  1653.     return std::string(temp.str);
  1654.   }
  1655.  
  1656.   // conversion functions
  1657.   mpz_srcptr __get_mp() const { return mp; }
  1658.   mpz_ptr __get_mp() { return mp; }
  1659.   mpz_srcptr get_mpz_t() const { return mp; }
  1660.   mpz_ptr get_mpz_t() { return mp; }
  1661.  
  1662.   signed long int get_si() const { return mpz_get_si(mp); }
  1663.   unsigned long int get_ui() const { return mpz_get_ui(mp); }
  1664.   double get_d() const { return mpz_get_d(mp); }
  1665.  
  1666.   // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
  1667.   // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
  1668.   bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
  1669.   bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
  1670.   bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
  1671.   bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
  1672.   bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
  1673.   bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
  1674.   // bool fits_float_p() const { return mpz_fits_float_p(mp); }
  1675.   // bool fits_double_p() const { return mpz_fits_double_p(mp); }
  1676.   // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
  1677.  
  1678.   // member operators
  1679.   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  1680.   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  1681.   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  1682.   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  1683.   __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
  1684.  
  1685.   __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
  1686.   __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
  1687.   __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
  1688.  
  1689.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  1690.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  1691.  
  1692.   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  1693.   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  1694. };
  1695.  
  1696. typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
  1697.  
  1698.  
  1699. /**************** mpq_class -- wrapper for mpq_t ****************/
  1700.  
  1701. template <>
  1702. class __gmp_expr<mpq_t, mpq_t>
  1703. {
  1704. private:
  1705.   typedef mpq_t value_type;
  1706.   value_type mp;
  1707. public:
  1708.   unsigned long int get_prec() const { return mpf_get_default_prec(); }
  1709.   void canonicalize() { mpq_canonicalize(mp); }
  1710.  
  1711.   // constructors and destructor
  1712.   __gmp_expr() { mpq_init(mp); }
  1713.  
  1714.   __gmp_expr(const __gmp_expr &q) { mpq_init(mp); mpq_set(mp, q.mp); }
  1715.   template <class T, class U>
  1716.   __gmp_expr(const __gmp_expr<T, U> &expr)
  1717.   { mpq_init(mp); __gmp_set_expr(mp, expr); }
  1718.  
  1719.   __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); }
  1720.   __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); }
  1721.  
  1722.   __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); }
  1723.   __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); }
  1724.  
  1725.   __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); }
  1726.   __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); }
  1727.  
  1728.   __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
  1729.   __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
  1730.  
  1731.   __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); }
  1732.   __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); }
  1733.   // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); }
  1734.  
  1735.   explicit __gmp_expr(const char *s)
  1736.   {
  1737.     mpq_init (mp);
  1738.     if (mpq_set_str (mp, s, 0) != 0)
  1739.       {
  1740.         mpq_clear (mp);
  1741.         throw std::invalid_argument ("mpq_set_str");
  1742.       }
  1743.   }
  1744.   __gmp_expr(const char *s, int base)
  1745.   {
  1746.     mpq_init (mp);
  1747.     if (mpq_set_str(mp, s, base) != 0)
  1748.       {
  1749.         mpq_clear (mp);
  1750.         throw std::invalid_argument ("mpq_set_str");
  1751.       }
  1752.   }
  1753.   explicit __gmp_expr(const std::string &s)
  1754.   {
  1755.     mpq_init (mp);
  1756.     if (mpq_set_str (mp, s.c_str(), 0) != 0)
  1757.       {
  1758.         mpq_clear (mp);
  1759.         throw std::invalid_argument ("mpq_set_str");
  1760.       }
  1761.   }
  1762.   __gmp_expr(const std::string &s, int base)
  1763.   {
  1764.     mpq_init(mp);
  1765.     if (mpq_set_str (mp, s.c_str(), base) != 0)
  1766.       {
  1767.         mpq_clear (mp);
  1768.         throw std::invalid_argument ("mpq_set_str");
  1769.       }
  1770.   }
  1771.   explicit __gmp_expr(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); }
  1772.  
  1773.   __gmp_expr(const mpz_class &num, const mpz_class &den)
  1774.   {
  1775.     mpq_init(mp);
  1776.     mpz_set(mpq_numref(mp), num.get_mpz_t());
  1777.     mpz_set(mpq_denref(mp), den.get_mpz_t());
  1778.   }
  1779.  
  1780.   ~__gmp_expr() { mpq_clear(mp); }
  1781.  
  1782.   // assignment operators
  1783.   __gmp_expr & operator=(const __gmp_expr &q)
  1784.   { mpq_set(mp, q.mp); return *this; }
  1785.   template <class T, class U>
  1786.   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1787.   { __gmp_set_expr(mp, expr); return *this; }
  1788.  
  1789.   __gmp_expr & operator=(signed char c)
  1790.   { mpq_set_si(mp, c, 1); return *this; }
  1791.   __gmp_expr & operator=(unsigned char c)
  1792.   { mpq_set_ui(mp, c, 1); return *this; }
  1793.  
  1794.   __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; }
  1795.   __gmp_expr & operator=(unsigned int i)
  1796.   { mpq_set_ui(mp, i, 1); return *this; }
  1797.  
  1798.   __gmp_expr & operator=(signed short int s)
  1799.   { mpq_set_si(mp, s, 1); return *this; }
  1800.   __gmp_expr & operator=(unsigned short int s)
  1801.   { mpq_set_ui(mp, s, 1); return *this; }
  1802.  
  1803.   __gmp_expr & operator=(signed long int l)
  1804.   { mpq_set_si(mp, l, 1); return *this; }
  1805.   __gmp_expr & operator=(unsigned long int l)
  1806.   { mpq_set_ui(mp, l, 1); return *this; }
  1807.  
  1808.   __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; }
  1809.   __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; }
  1810.   // __gmp_expr & operator=(long double ld)
  1811.   // { mpq_set_ld(mp, ld); return *this; }
  1812.  
  1813.   __gmp_expr & operator=(const char *s)
  1814.   {
  1815.     if (mpq_set_str (mp, s, 0) != 0)
  1816.       throw std::invalid_argument ("mpq_set_str");
  1817.     return *this;
  1818.   }
  1819.   __gmp_expr & operator=(const std::string &s)
  1820.   {
  1821.     if (mpq_set_str(mp, s.c_str(), 0) != 0)
  1822.       throw std::invalid_argument ("mpq_set_str");
  1823.     return *this;
  1824.   }
  1825.  
  1826.   // string input/output functions
  1827.   int set_str(const char *s, int base)
  1828.   { return mpq_set_str(mp, s, base); }
  1829.   int set_str(const std::string &s, int base)
  1830.   { return mpq_set_str(mp, s.c_str(), base); }
  1831.   std::string get_str(int base = 10) const
  1832.   {
  1833.     __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
  1834.     return std::string(temp.str);
  1835.   }
  1836.  
  1837.   // conversion functions
  1838.  
  1839.   // casting a reference to an mpz_t to mpz_class & is a dirty hack,
  1840.   // but works because the internal representation of mpz_class is
  1841.   // exactly an mpz_t
  1842.   const mpz_class & get_num() const
  1843.   { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
  1844.   mpz_class & get_num()
  1845.   { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
  1846.   const mpz_class & get_den() const
  1847.   { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
  1848.   mpz_class & get_den()
  1849.   { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
  1850.  
  1851.   mpq_srcptr __get_mp() const { return mp; }
  1852.   mpq_ptr __get_mp() { return mp; }
  1853.   mpq_srcptr get_mpq_t() const { return mp; }
  1854.   mpq_ptr get_mpq_t() { return mp; }
  1855.  
  1856.   mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
  1857.   mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
  1858.   mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
  1859.   mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
  1860.  
  1861.   double get_d() const { return mpq_get_d(mp); }
  1862.  
  1863.   // compound assignments
  1864.   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  1865.   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  1866.   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  1867.   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  1868.  
  1869.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  1870.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  1871.  
  1872.   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  1873.   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  1874. };
  1875.  
  1876. typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
  1877.  
  1878.  
  1879. /**************** mpf_class -- wrapper for mpf_t ****************/
  1880.  
  1881. template <>
  1882. class __gmp_expr<mpf_t, mpf_t>
  1883. {
  1884. private:
  1885.   typedef mpf_t value_type;
  1886.   value_type mp;
  1887. public:
  1888.   unsigned long int get_prec() const { return mpf_get_prec(mp); }
  1889.  
  1890.   void set_prec(unsigned long int prec) { mpf_set_prec(mp, prec); }
  1891.   void set_prec_raw(unsigned long int prec) { mpf_set_prec_raw(mp, prec); }
  1892.  
  1893.   // constructors and destructor
  1894.   __gmp_expr() { mpf_init(mp); }
  1895.  
  1896.   __gmp_expr(const __gmp_expr &f)
  1897.   { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
  1898.   __gmp_expr(const __gmp_expr &f, unsigned long int prec)
  1899.   { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
  1900.   template <class T, class U>
  1901.   __gmp_expr(const __gmp_expr<T, U> &expr)
  1902.   { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
  1903.   template <class T, class U>
  1904.   __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
  1905.   { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
  1906.  
  1907.   __gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
  1908.   __gmp_expr(signed char c, unsigned long int prec)
  1909.   { mpf_init2(mp, prec); mpf_set_si(mp, c); }
  1910.   __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
  1911.   __gmp_expr(unsigned char c, unsigned long int prec)
  1912.   { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
  1913.  
  1914.   __gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
  1915.   __gmp_expr(signed int i, unsigned long int prec)
  1916.   { mpf_init2(mp, prec); mpf_set_si(mp, i); }
  1917.   __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
  1918.   __gmp_expr(unsigned int i, unsigned long int prec)
  1919.   { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
  1920.  
  1921.   __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
  1922.   __gmp_expr(signed short int s, unsigned long int prec)
  1923.   { mpf_init2(mp, prec); mpf_set_si(mp, s); }
  1924.   __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
  1925.   __gmp_expr(unsigned short int s, unsigned long int prec)
  1926.   { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
  1927.  
  1928.   __gmp_expr(signed long int l) { mpf_init_set_si(mp, l); }
  1929.   __gmp_expr(signed long int l, unsigned long int prec)
  1930.   { mpf_init2(mp, prec); mpf_set_si(mp, l); }
  1931.   __gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); }
  1932.   __gmp_expr(unsigned long int l, unsigned long int prec)
  1933.   { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
  1934.  
  1935.   __gmp_expr(float f) { mpf_init_set_d(mp, f); }
  1936.   __gmp_expr(float f, unsigned long int prec)
  1937.   { mpf_init2(mp, prec); mpf_set_d(mp, f); }
  1938.   __gmp_expr(double d) { mpf_init_set_d(mp, d); }
  1939.   __gmp_expr(double d, unsigned long int prec)
  1940.   { mpf_init2(mp, prec); mpf_set_d(mp, d); }
  1941.   // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
  1942.   // __gmp_expr(long double ld, unsigned long int prec)
  1943.   // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
  1944.  
  1945.   explicit __gmp_expr(const char *s)
  1946.   {
  1947.     if (mpf_init_set_str (mp, s, 0) != 0)
  1948.       {
  1949.         mpf_clear (mp);
  1950.         throw std::invalid_argument ("mpf_set_str");
  1951.       }
  1952.   }
  1953.   __gmp_expr(const char *s, unsigned long int prec, int base = 0)
  1954.   {
  1955.     mpf_init2(mp, prec);
  1956.     if (mpf_set_str(mp, s, base) != 0)
  1957.       {
  1958.         mpf_clear (mp);
  1959.         throw std::invalid_argument ("mpf_set_str");
  1960.       }
  1961.   }
  1962.   explicit __gmp_expr(const std::string &s)
  1963.   {
  1964.     if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
  1965.       {
  1966.         mpf_clear (mp);
  1967.         throw std::invalid_argument ("mpf_set_str");
  1968.       }
  1969.   }
  1970.   __gmp_expr(const std::string &s, unsigned long int prec, int base = 0)
  1971.   {
  1972.     mpf_init2(mp, prec);
  1973.     if (mpf_set_str(mp, s.c_str(), base) != 0)
  1974.       {
  1975.         mpf_clear (mp);
  1976.         throw std::invalid_argument ("mpf_set_str");
  1977.       }
  1978.   }
  1979.  
  1980.   explicit __gmp_expr(mpf_srcptr f)
  1981.   { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
  1982.   __gmp_expr(mpf_srcptr f, unsigned long int prec)
  1983.   { mpf_init2(mp, prec); mpf_set(mp, f); }
  1984.  
  1985.   ~__gmp_expr() { mpf_clear(mp); }
  1986.  
  1987.   // assignment operators
  1988.   __gmp_expr & operator=(const __gmp_expr &f)
  1989.   { mpf_set(mp, f.mp); return *this; }
  1990.   template <class T, class U>
  1991.   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
  1992.   { __gmp_set_expr(mp, expr); return *this; }
  1993.  
  1994.   __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; }
  1995.   __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; }
  1996.  
  1997.   __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; }
  1998.   __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; }
  1999.  
  2000.   __gmp_expr & operator=(signed short int s)
  2001.   { mpf_set_si(mp, s); return *this; }
  2002.   __gmp_expr & operator=(unsigned short int s)
  2003.   { mpf_set_ui(mp, s); return *this; }
  2004.  
  2005.   __gmp_expr & operator=(signed long int l)
  2006.   { mpf_set_si(mp, l); return *this; }
  2007.   __gmp_expr & operator=(unsigned long int l)
  2008.   { mpf_set_ui(mp, l); return *this; }
  2009.  
  2010.   __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; }
  2011.   __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; }
  2012.   // __gmp_expr & operator=(long double ld)
  2013.   // { mpf_set_ld(mp, ld); return *this; }
  2014.  
  2015.   __gmp_expr & operator=(const char *s)
  2016.   {
  2017.     if (mpf_set_str (mp, s, 0) != 0)
  2018.       throw std::invalid_argument ("mpf_set_str");
  2019.     return *this;
  2020.   }
  2021.   __gmp_expr & operator=(const std::string &s)
  2022.   {
  2023.     if (mpf_set_str(mp, s.c_str(), 0) != 0)
  2024.       throw std::invalid_argument ("mpf_set_str");
  2025.     return *this;
  2026.   }
  2027.  
  2028.   // string input/output functions
  2029.   int set_str(const char *s, int base)
  2030.   { return mpf_set_str(mp, s, base); }
  2031.   int set_str(const std::string &s, int base)
  2032.   { return mpf_set_str(mp, s.c_str(), base); }
  2033.   std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
  2034.   {
  2035.     __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
  2036.     return std::string(temp.str);
  2037.   }
  2038.  
  2039.   // conversion functions
  2040.   mpf_srcptr __get_mp() const { return mp; }
  2041.   mpf_ptr __get_mp() { return mp; }
  2042.   mpf_srcptr get_mpf_t() const { return mp; }
  2043.   mpf_ptr get_mpf_t() { return mp; }
  2044.  
  2045.   signed long int get_si() const { return mpf_get_si(mp); }
  2046.   unsigned long int get_ui() const { return mpf_get_ui(mp); }
  2047.   double get_d() const { return mpf_get_d(mp); }
  2048.  
  2049.   // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
  2050.   // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
  2051.   bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
  2052.   bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
  2053.   bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
  2054.   bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
  2055.   bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
  2056.   bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
  2057.   // bool fits_float_p() const { return mpf_fits_float_p(mp); }
  2058.   // bool fits_double_p() const { return mpf_fits_double_p(mp); }
  2059.   // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
  2060.  
  2061.   // compound assignments
  2062.   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
  2063.   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
  2064.   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
  2065.   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
  2066.  
  2067.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
  2068.   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
  2069.  
  2070.   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
  2071.   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
  2072. };
  2073.  
  2074. typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
  2075.  
  2076.  
  2077.  
  2078. /**************** I/O operators ****************/
  2079.  
  2080. // these should (and will) be provided separately
  2081.  
  2082. template <class T>
  2083. inline std::ostream & operator<<
  2084. (std::ostream &o, const __gmp_expr<T, T> &expr)
  2085. {
  2086.   return o << expr.__get_mp();
  2087. }
  2088.  
  2089. template <class T, class U>
  2090. inline std::ostream & operator<<
  2091. (std::ostream &o, const __gmp_expr<T, U> &expr)
  2092. {
  2093.   __gmp_expr<T, T> temp(expr);
  2094.   return o << temp.__get_mp();
  2095. }
  2096.  
  2097.  
  2098. template <class T>
  2099. inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
  2100. {
  2101.   return i >> expr.__get_mp();
  2102. }
  2103.  
  2104. inline std::istream & operator>>(std::istream &i, mpq_class &q)
  2105. {
  2106.   i >> q.get_mpq_t();
  2107.   // q.canonicalize(); // you might want to uncomment this
  2108.   return i;
  2109. }
  2110.  
  2111.  
  2112. /**************** Functions for type conversion ****************/
  2113.  
  2114. template <>
  2115. inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
  2116. {
  2117.   mpz_set(z, w.get_mpz_t());
  2118. }
  2119.  
  2120. template <class T>
  2121. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
  2122. {
  2123.   expr.eval(z);
  2124. }
  2125.  
  2126. template <>
  2127. inline void __gmp_set_expr(mpz_ptr z, const mpq_class &q)
  2128. {
  2129.   mpz_set_q(z, q.get_mpq_t());
  2130. }
  2131.  
  2132. template <class T>
  2133. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
  2134. {
  2135.   mpq_class temp(expr);
  2136.   mpz_set_q(z, temp.get_mpq_t());
  2137. }
  2138.  
  2139. template <class T>
  2140. inline void __gmp_set_expr(mpz_ptr z, const mpf_class &f)
  2141. {
  2142.   mpz_set_f(z, f.get_mpf_t());
  2143. }
  2144.  
  2145. template <class T>
  2146. inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
  2147. {
  2148.   mpf_class temp(expr);
  2149.   mpz_set_f(z, temp.get_mpf_t());
  2150. }
  2151.  
  2152. template <>
  2153. inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
  2154. {
  2155.   mpq_set_z(q, z.get_mpz_t());
  2156. }
  2157.  
  2158. template <class T>
  2159. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
  2160. {
  2161.   mpz_class temp(expr);
  2162.   mpq_set_z(q, temp.get_mpz_t());
  2163. }
  2164.  
  2165. template <>
  2166. inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
  2167. {
  2168.   mpq_set(q, r.get_mpq_t());
  2169. }
  2170.  
  2171. template <class T>
  2172. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
  2173. {
  2174.   expr.eval(q);
  2175. }
  2176.  
  2177. template <class T>
  2178. inline void __gmp_set_expr(mpq_ptr q, const mpf_class &f)
  2179. {
  2180.   mpq_set_f(q, f.get_mpf_t());
  2181. }
  2182.  
  2183. template <class T>
  2184. inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
  2185. {
  2186.   mpf_class temp(expr);
  2187.   mpq_set_f(q, temp.get_mpf_t());
  2188. }
  2189.  
  2190. template <class T>
  2191. inline void __gmp_set_expr(mpf_ptr f, const mpz_class &z)
  2192. {
  2193.   mpf_set_z(f, z.get_mpz_t());
  2194. }
  2195.  
  2196. template <class T>
  2197. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
  2198. {
  2199.   mpz_class temp(expr);
  2200.   mpf_set_z(f, temp.get_mpz_t());
  2201. }
  2202.  
  2203. template <class T>
  2204. inline void __gmp_set_expr(mpf_ptr f, const mpq_class &q)
  2205. {
  2206.   mpf_set_q(f, q.get_mpq_t());
  2207. }
  2208.  
  2209. template <class T>
  2210. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
  2211. {
  2212.   mpq_class temp(expr);
  2213.   mpf_set_q(f, temp.get_mpq_t());
  2214. }
  2215.  
  2216. template <>
  2217. inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
  2218. {
  2219.   mpf_set(f, g.get_mpf_t());
  2220. }
  2221.  
  2222. template <class T>
  2223. inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
  2224. {
  2225.   expr.eval(f, mpf_get_prec(f));
  2226. }
  2227.  
  2228.  
  2229. /**************** Specializations of __gmp_expr ****************/
  2230. /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
  2231.    expression and assigns the result to its argument, which is either an
  2232.    mpz_t, mpq_t, or mpf_t as specified by the T argument.
  2233.    Compound expressions are evaluated recursively (temporaries are created
  2234.    to hold intermediate values), while for simple expressions the eval()
  2235.    method of the appropriate function object (available as the Op argument
  2236.    of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
  2237.    called. */
  2238.  
  2239.  
  2240. /**************** Unary expressions ****************/
  2241. /* cases:
  2242.    - simple:   argument is mp*_class, that is, __gmp_expr<T, T>
  2243.    - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
  2244.  
  2245.  
  2246. // simple expressions
  2247.  
  2248. template <class T, class Op>
  2249. class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
  2250. {
  2251. private:
  2252.   typedef __gmp_expr<T, T> val_type;
  2253.  
  2254.   __gmp_unary_expr<val_type, Op> expr;
  2255. public:
  2256.   __gmp_expr(const val_type &val) : expr(val) { }
  2257.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2258.         unsigned long int = 0) const
  2259.   { Op::eval(p, expr.val.__get_mp()); }
  2260.   const val_type & get_val() const { return expr.val; }
  2261.   unsigned long int get_prec() const { return expr.val.get_prec(); }
  2262. };
  2263.  
  2264.  
  2265. // compound expressions
  2266.  
  2267. template <class T, class U, class Op>
  2268. class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
  2269. {
  2270. private:
  2271.   typedef __gmp_expr<T, U> val_type;
  2272.  
  2273.   __gmp_unary_expr<val_type, Op> expr;
  2274. public:
  2275.   __gmp_expr(const val_type &val) : expr(val) { }
  2276.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2277.   { __gmp_expr<T, T> temp(expr.val); Op::eval(p, temp.__get_mp()); }
  2278.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2279.         unsigned long int prec) const
  2280.   { __gmp_expr<T, T> temp(expr.val, prec); Op::eval(p, temp.__get_mp()); }
  2281.   const val_type & get_val() const { return expr.val; }
  2282.   unsigned long int get_prec() const { return expr.val.get_prec(); }
  2283. };
  2284.  
  2285.  
  2286. /**************** Binary expressions ****************/
  2287. /* simple:
  2288.    - arguments are both mp*_class
  2289.    - one argument is mp*_class, one is a built-in type
  2290.    compound:
  2291.    - one is mp*_class, one is __gmp_expr<T, U>
  2292.    - one is __gmp_expr<T, U>, one is built-in
  2293.    - both arguments are __gmp_expr<...> */
  2294.  
  2295.  
  2296. // simple expressions
  2297.  
  2298. template <class T, class Op>
  2299. class __gmp_expr
  2300. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
  2301. {
  2302. private:
  2303.   typedef __gmp_expr<T, T> val1_type;
  2304.   typedef __gmp_expr<T, T> val2_type;
  2305.  
  2306.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2307. public:
  2308.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2309.     : expr(val1, val2) { }
  2310.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2311.         unsigned long int = 0) const
  2312.   { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
  2313.   const val1_type & get_val1() const { return expr.val1; }
  2314.   const val2_type & get_val2() const { return expr.val2; }
  2315.   unsigned long int get_prec() const
  2316.   {
  2317.     unsigned long int prec1 = expr.val1.get_prec(),
  2318.       prec2 = expr.val2.get_prec();
  2319.     return (prec1 > prec2) ? prec1 : prec2;
  2320.   }
  2321. };
  2322.  
  2323.  
  2324. // simple expressions, T is a built-in numerical type
  2325.  
  2326. template <class T, class U, class Op>
  2327. class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
  2328. {
  2329. private:
  2330.   typedef __gmp_expr<T, T> val1_type;
  2331.   typedef U val2_type;
  2332.  
  2333.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2334. public:
  2335.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2336.     : expr(val1, val2) { }
  2337.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2338.         unsigned long int = 0) const
  2339.   { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
  2340.   const val1_type & get_val1() const { return expr.val1; }
  2341.   const val2_type & get_val2() const { return expr.val2; }
  2342.   unsigned long int get_prec() const { return expr.val1.get_prec(); }
  2343. };
  2344.  
  2345. template <class T, class U, class Op>
  2346. class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
  2347. {
  2348. private:
  2349.   typedef U val1_type;
  2350.   typedef __gmp_expr<T, T> val2_type;
  2351.  
  2352.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2353. public:
  2354.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2355.     : expr(val1, val2) { }
  2356.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2357.         unsigned long int = 0) const
  2358.   { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
  2359.   const val1_type & get_val1() const { return expr.val1; }
  2360.   const val2_type & get_val2() const { return expr.val2; }
  2361.   unsigned long int get_prec() const { return expr.val2.get_prec(); }
  2362. };
  2363.  
  2364.  
  2365. // compound expressions, one argument is a subexpression
  2366.  
  2367. template <class T, class U, class V, class Op>
  2368. class __gmp_expr
  2369. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
  2370. {
  2371. private:
  2372.   typedef __gmp_expr<T, T> val1_type;
  2373.   typedef __gmp_expr<U, V> val2_type;
  2374.  
  2375.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2376. public:
  2377.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2378.     : expr(val1, val2) { }
  2379.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2380.   {
  2381.     __gmp_expr<T, T> temp(expr.val2);
  2382.     Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2383.   }
  2384.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2385.         unsigned long int prec) const
  2386.   {
  2387.     __gmp_expr<T, T> temp(expr.val2, prec);
  2388.     Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2389.   }
  2390.   const val1_type & get_val1() const { return expr.val1; }
  2391.   const val2_type & get_val2() const { return expr.val2; }
  2392.   unsigned long int get_prec() const
  2393.   {
  2394.     unsigned long int prec1 = expr.val1.get_prec(),
  2395.       prec2 = expr.val2.get_prec();
  2396.     return (prec1 > prec2) ? prec1 : prec2;
  2397.   }
  2398. };
  2399.  
  2400. template <class T, class U, class V, class Op>
  2401. class __gmp_expr
  2402. <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
  2403. {
  2404. private:
  2405.   typedef __gmp_expr<U, V> val1_type;
  2406.   typedef __gmp_expr<T, T> val2_type;
  2407.  
  2408.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2409. public:
  2410.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2411.     : expr(val1, val2) { }
  2412.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2413.   {
  2414.     __gmp_expr<T, T> temp(expr.val1);
  2415.     Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2416.   }
  2417.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2418.         unsigned long int prec) const
  2419.   {
  2420.     __gmp_expr<T, T> temp(expr.val1, prec);
  2421.     Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2422.   }
  2423.   const val1_type & get_val1() const { return expr.val1; }
  2424.   const val2_type & get_val2() const { return expr.val2; }
  2425.   unsigned long int get_prec() const
  2426.   {
  2427.     unsigned long int prec1 = expr.val1.get_prec(),
  2428.       prec2 = expr.val2.get_prec();
  2429.     return (prec1 > prec2) ? prec1 : prec2;
  2430.   }
  2431. };
  2432.  
  2433. template <class T, class U, class Op>
  2434. class __gmp_expr
  2435. <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
  2436. {
  2437. private:
  2438.   typedef __gmp_expr<T, T> val1_type;
  2439.   typedef __gmp_expr<T, U> val2_type;
  2440.  
  2441.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2442. public:
  2443.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2444.     : expr(val1, val2) { }
  2445.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2446.   {
  2447.     __gmp_expr<T, T> temp(expr.val2);
  2448.     Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2449.   }
  2450.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2451.         unsigned long int prec) const
  2452.   {
  2453.     __gmp_expr<T, T> temp(expr.val2, prec);
  2454.     Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
  2455.   }
  2456.   const val1_type & get_val1() const { return expr.val1; }
  2457.   const val2_type & get_val2() const { return expr.val2; }
  2458.   unsigned long int get_prec() const
  2459.   {
  2460.     unsigned long int prec1 = expr.val1.get_prec(),
  2461.       prec2 = expr.val2.get_prec();
  2462.     return (prec1 > prec2) ? prec1 : prec2;
  2463.   }
  2464. };
  2465.  
  2466. template <class T, class U, class Op>
  2467. class __gmp_expr
  2468. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
  2469. {
  2470. private:
  2471.   typedef __gmp_expr<T, U> val1_type;
  2472.   typedef __gmp_expr<T, T> val2_type;
  2473.  
  2474.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2475. public:
  2476.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2477.     : expr(val1, val2) { }
  2478.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2479.   {
  2480.     __gmp_expr<T, T> temp(expr.val1);
  2481.     Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2482.   }
  2483.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2484.         unsigned long int prec) const
  2485.   {
  2486.     __gmp_expr<T, T> temp(expr.val1, prec);
  2487.     Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
  2488.   }
  2489.   const val1_type & get_val1() const { return expr.val1; }
  2490.   const val2_type & get_val2() const { return expr.val2; }
  2491.   unsigned long int get_prec() const
  2492.   {
  2493.     unsigned long int prec1 = expr.val1.get_prec(),
  2494.       prec2 = expr.val2.get_prec();
  2495.     return (prec1 > prec2) ? prec1 : prec2;
  2496.   }
  2497. };
  2498.  
  2499.  
  2500. // one argument is a subexpression, one is a built-in
  2501.  
  2502. template <class T, class U, class V, class Op>
  2503. class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
  2504. {
  2505. private:
  2506.   typedef __gmp_expr<T, U> val1_type;
  2507.   typedef V val2_type;
  2508.  
  2509.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2510. public:
  2511.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2512.     : expr(val1, val2) { }
  2513.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2514.   {
  2515.     __gmp_expr<T, T> temp(expr.val1);
  2516.     Op::eval(p, temp.__get_mp(), expr.val2);
  2517.   }
  2518.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2519.         unsigned long int prec) const
  2520.   {
  2521.     __gmp_expr<T, T> temp(expr.val1, prec);
  2522.     Op::eval(p, temp.__get_mp(), expr.val2);
  2523.   }
  2524.   const val1_type & get_val1() const { return expr.val1; }
  2525.   const val2_type & get_val2() const { return expr.val2; }
  2526.   unsigned long int get_prec() const { return expr.val1.get_prec(); }
  2527. };
  2528.  
  2529. template <class T, class U, class V, class Op>
  2530. class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
  2531. {
  2532. private:
  2533.   typedef U val1_type;
  2534.   typedef __gmp_expr<T, V> val2_type;
  2535.  
  2536.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2537. public:
  2538.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2539.     : expr(val1, val2) { }
  2540.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2541.   {
  2542.     __gmp_expr<T, T> temp(expr.val2);
  2543.     Op::eval(p, expr.val1, temp.__get_mp());
  2544.   }
  2545.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2546.         unsigned long int prec) const
  2547.   {
  2548.     __gmp_expr<T, T> temp(expr.val2, prec);
  2549.     Op::eval(p, expr.val1, temp.__get_mp());
  2550.   }
  2551.   const val1_type & get_val1() const { return expr.val1; }
  2552.   const val2_type & get_val2() const { return expr.val2; }
  2553.   unsigned long int get_prec() const { return expr.val2.get_prec(); }
  2554. };
  2555.  
  2556.  
  2557. // both arguments are subexpressions
  2558.  
  2559. template <class T, class U, class V, class W, class Op>
  2560. class __gmp_expr
  2561. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
  2562. {
  2563. private:
  2564.   typedef __gmp_expr<T, U> val1_type;
  2565.   typedef __gmp_expr<V, W> val2_type;
  2566.  
  2567.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2568. public:
  2569.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2570.     : expr(val1, val2) { }
  2571.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2572.   {
  2573.     __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
  2574.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2575.   }
  2576.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2577.         unsigned long int prec) const
  2578.   {
  2579.     __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
  2580.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2581.   }
  2582.   const val1_type & get_val1() const { return expr.val1; }
  2583.   const val2_type & get_val2() const { return expr.val2; }
  2584.   unsigned long int get_prec() const
  2585.   {
  2586.     unsigned long int prec1 = expr.val1.get_prec(),
  2587.       prec2 = expr.val2.get_prec();
  2588.     return (prec1 > prec2) ? prec1 : prec2;
  2589.   }
  2590. };
  2591.  
  2592. template <class T, class U, class V, class W, class Op>
  2593. class __gmp_expr
  2594. <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
  2595. {
  2596. private:
  2597.   typedef __gmp_expr<U, V> val1_type;
  2598.   typedef __gmp_expr<T, W> val2_type;
  2599.  
  2600.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2601. public:
  2602.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2603.     : expr(val1, val2) { }
  2604.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2605.   {
  2606.     __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
  2607.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2608.   }
  2609.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2610.         unsigned long int prec) const
  2611.   {
  2612.     __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
  2613.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2614.   }
  2615.   const val1_type & get_val1() const { return expr.val1; }
  2616.   const val2_type & get_val2() const { return expr.val2; }
  2617.   unsigned long int get_prec() const
  2618.   {
  2619.     unsigned long int prec1 = expr.val1.get_prec(),
  2620.       prec2 = expr.val2.get_prec();
  2621.     return (prec1 > prec2) ? prec1 : prec2;
  2622.   }
  2623. };
  2624.  
  2625. template <class T, class U, class V, class Op>
  2626. class __gmp_expr
  2627. <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
  2628. {
  2629. private:
  2630.   typedef __gmp_expr<T, U> val1_type;
  2631.   typedef __gmp_expr<T, V> val2_type;
  2632.  
  2633.   __gmp_binary_expr<val1_type, val2_type, Op> expr;
  2634. public:
  2635.   __gmp_expr(const val1_type &val1, const val2_type &val2)
  2636.     : expr(val1, val2) { }
  2637.   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
  2638.   {
  2639.     __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
  2640.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2641.   }
  2642.   void eval(typename __gmp_resolve_expr<T>::ptr_type p,
  2643.         unsigned long int prec) const
  2644.   {
  2645.     __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
  2646.     Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
  2647.   }
  2648.   const val1_type & get_val1() const { return expr.val1; }
  2649.   const val2_type & get_val2() const { return expr.val2; }
  2650.   unsigned long int get_prec() const
  2651.   {
  2652.     unsigned long int prec1 = expr.val1.get_prec(),
  2653.       prec2 = expr.val2.get_prec();
  2654.     return (prec1 > prec2) ? prec1 : prec2;
  2655.   }
  2656. };
  2657.  
  2658.  
  2659. /**************** Special cases ****************/
  2660.  
  2661. /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
  2662.    can be done directly without first converting the mpz to mpq.
  2663.    Appropriate specializations of __gmp_expr are required. */
  2664.  
  2665.  
  2666. #define __GMPZQ_DEFINE_EXPR(eval_fun)                                       \
  2667.                                                                             \
  2668. template <>                                                                 \
  2669. class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
  2670. {                                                                           \
  2671. private:                                                                    \
  2672.   typedef mpz_class val1_type;                                              \
  2673.   typedef mpq_class val2_type;                                              \
  2674.                                                                             \
  2675.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2676. public:                                                                     \
  2677.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2678.     : expr(val1, val2) { }                                                  \
  2679.   void eval(mpq_ptr q) const                                                \
  2680.   { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); }      \
  2681.   const val1_type & get_val1() const { return expr.val1; }                  \
  2682.   const val2_type & get_val2() const { return expr.val2; }                  \
  2683.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2684. };                                                                          \
  2685.                                                                             \
  2686. template <>                                                                 \
  2687. class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
  2688. {                                                                           \
  2689. private:                                                                    \
  2690.   typedef mpq_class val1_type;                                              \
  2691.   typedef mpz_class val2_type;                                              \
  2692.                                                                             \
  2693.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2694. public:                                                                     \
  2695.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2696.     : expr(val1, val2) { }                                                  \
  2697.   void eval(mpq_ptr q) const                                                \
  2698.   { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); }      \
  2699.   const val1_type & get_val1() const { return expr.val1; }                  \
  2700.   const val2_type & get_val2() const { return expr.val2; }                  \
  2701.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2702. };                                                                          \
  2703.                                                                             \
  2704. template <class T>                                                          \
  2705. class __gmp_expr                                                            \
  2706. <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> >      \
  2707. {                                                                           \
  2708. private:                                                                    \
  2709.   typedef mpz_class val1_type;                                              \
  2710.   typedef __gmp_expr<mpq_t, T> val2_type;                                   \
  2711.                                                                             \
  2712.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2713. public:                                                                     \
  2714.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2715.     : expr(val1, val2) { }                                                  \
  2716.   void eval(mpq_ptr q) const                                                \
  2717.   {                                                                         \
  2718.     mpq_class temp(expr.val2);                                              \
  2719.     eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t());             \
  2720.   }                                                                         \
  2721.   const val1_type & get_val1() const { return expr.val1; }                  \
  2722.   const val2_type & get_val2() const { return expr.val2; }                  \
  2723.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2724. };                                                                          \
  2725.                                                                             \
  2726. template <class T>                                                          \
  2727. class __gmp_expr                                                            \
  2728. <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> >      \
  2729. {                                                                           \
  2730. private:                                                                    \
  2731.   typedef mpq_class val1_type;                                              \
  2732.   typedef __gmp_expr<mpz_t, T> val2_type;                                   \
  2733.                                                                             \
  2734.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2735. public:                                                                     \
  2736.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2737.     : expr(val1, val2) { }                                                  \
  2738.   void eval(mpq_ptr q) const                                                \
  2739.   {                                                                         \
  2740.     mpz_class temp(expr.val2);                                              \
  2741.     eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t());             \
  2742.   }                                                                         \
  2743.   const val1_type & get_val1() const { return expr.val1; }                  \
  2744.   const val2_type & get_val2() const { return expr.val2; }                  \
  2745.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2746. };                                                                          \
  2747.                                                                             \
  2748. template <class T>                                                          \
  2749. class __gmp_expr                                                            \
  2750. <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> >      \
  2751. {                                                                           \
  2752. private:                                                                    \
  2753.   typedef __gmp_expr<mpz_t, T> val1_type;                                   \
  2754.   typedef mpq_class val2_type;                                              \
  2755.                                                                             \
  2756.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2757. public:                                                                     \
  2758.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2759.     : expr(val1, val2) { }                                                  \
  2760.   void eval(mpq_ptr q) const                                                \
  2761.   {                                                                         \
  2762.     mpz_class temp(expr.val1);                                              \
  2763.     eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t());             \
  2764.   }                                                                         \
  2765.   const val1_type & get_val1() const { return expr.val1; }                  \
  2766.   const val2_type & get_val2() const { return expr.val2; }                  \
  2767.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2768. };                                                                          \
  2769.                                                                             \
  2770. template <class T>                                                          \
  2771. class __gmp_expr                                                            \
  2772. <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> >      \
  2773. {                                                                           \
  2774. private:                                                                    \
  2775.   typedef __gmp_expr<mpq_t, T> val1_type;                                   \
  2776.   typedef mpz_class val2_type;                                              \
  2777.                                                                             \
  2778.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2779. public:                                                                     \
  2780.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2781.     : expr(val1, val2) { }                                                  \
  2782.   void eval(mpq_ptr q) const                                                \
  2783.   {                                                                         \
  2784.     mpq_class temp(expr.val1);                                              \
  2785.     eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t());             \
  2786.   }                                                                         \
  2787.   const val1_type & get_val1() const { return expr.val1; }                  \
  2788.   const val2_type & get_val2() const { return expr.val2; }                  \
  2789.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2790. };                                                                          \
  2791.                                                                             \
  2792. template <class T, class U>                                                 \
  2793. class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
  2794. <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> >                    \
  2795. {                                                                           \
  2796. private:                                                                    \
  2797.   typedef __gmp_expr<mpz_t, T> val1_type;                                   \
  2798.   typedef __gmp_expr<mpq_t, U> val2_type;                                   \
  2799.                                                                             \
  2800.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2801. public:                                                                     \
  2802.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2803.     : expr(val1, val2) { }                                                  \
  2804.   void eval(mpq_ptr q) const                                                \
  2805.   {                                                                         \
  2806.     mpz_class temp1(expr.val1);                                             \
  2807.     mpq_class temp2(expr.val2);                                             \
  2808.     eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t());                \
  2809.   }                                                                         \
  2810.   const val1_type & get_val1() const { return expr.val1; }                  \
  2811.   const val2_type & get_val2() const { return expr.val2; }                  \
  2812.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2813. };                                                                          \
  2814.                                                                             \
  2815. template <class T, class U>                                                 \
  2816. class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
  2817. <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> >                    \
  2818. {                                                                           \
  2819. private:                                                                    \
  2820.   typedef __gmp_expr<mpq_t, T> val1_type;                                   \
  2821.   typedef __gmp_expr<mpz_t, U> val2_type;                                   \
  2822.                                                                             \
  2823.   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
  2824. public:                                                                     \
  2825.   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
  2826.     : expr(val1, val2) { }                                                  \
  2827.   void eval(mpq_ptr q) const                                                \
  2828.   {                                                                         \
  2829.     mpq_class temp1(expr.val1);                                             \
  2830.     mpz_class temp2(expr.val2);                                             \
  2831.     eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t());                \
  2832.   }                                                                         \
  2833.   const val1_type & get_val1() const { return expr.val1; }                  \
  2834.   const val2_type & get_val2() const { return expr.val2; }                  \
  2835.   unsigned long int get_prec() const { return mpf_get_default_prec(); }     \
  2836. };
  2837.  
  2838.  
  2839. __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
  2840. __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
  2841.  
  2842.  
  2843.  
  2844. /**************** Macros for defining functions ****************/
  2845. /* Results of operators and functions are instances of __gmp_expr<T, U>.
  2846.    T determines the numerical type of the expression: it can be either
  2847.    mpz_t, mpq_t, or mpf_t.  When the arguments of a binary
  2848.    expression have different numerical types, __gmp_resolve_expr is used
  2849.    to determine the "larger" type.
  2850.    U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
  2851.    where V and W are the arguments' types -- they can in turn be
  2852.    expressions, thus allowing to build compound expressions to any
  2853.    degree of complexity.
  2854.    Op is a function object that must have an eval() method accepting
  2855.    appropriate arguments.
  2856.    Actual evaluation of a __gmp_expr<T, U> object is done when it gets
  2857.    assigned to an mp*_class ("lazy" evaluation): this is done by calling
  2858.    its eval() method. */
  2859.  
  2860.  
  2861. // non-member unary operators and functions
  2862.  
  2863. #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun)                           \
  2864.                                                                              \
  2865. template <class T, class U>                                                  \
  2866. inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
  2867. fun(const __gmp_expr<T, U> &expr)                                            \
  2868. {                                                                            \
  2869.   return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
  2870. }
  2871.  
  2872. #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
  2873.                                                               \
  2874. template <class T, class U>                                   \
  2875. inline type fun(const __gmp_expr<T, U> &expr)                 \
  2876. {                                                             \
  2877.   typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
  2878.   return eval_fun::eval(temp.__get_mp());                     \
  2879. }
  2880.  
  2881.  
  2882. // non-member binary operators and functions
  2883.  
  2884. #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)                   \
  2885.                                                                        \
  2886. template <class T, class U, class V, class W>                          \
  2887. inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,       \
  2888. __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> >      \
  2889. fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2)      \
  2890. {                                                                      \
  2891.   return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,     \
  2892.      __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
  2893.     (expr1, expr2);                                                    \
  2894. }
  2895.  
  2896. #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype)       \
  2897.                                                                            \
  2898. template <class T, class U>                                                \
  2899. inline __gmp_expr                                                          \
  2900. <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >               \
  2901. fun(const __gmp_expr<T, U> &expr, type t)                                  \
  2902. {                                                                          \
  2903.   return __gmp_expr                                                        \
  2904.     <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
  2905. }                                                                          \
  2906.                                                                            \
  2907. template <class T, class U>                                                \
  2908. inline __gmp_expr                                                          \
  2909. <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >               \
  2910. fun(type t, const __gmp_expr<T, U> &expr)                                  \
  2911. {                                                                          \
  2912.   return __gmp_expr                                                        \
  2913.     <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
  2914. }
  2915.  
  2916. #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)          \
  2917. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
  2918.  
  2919. #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)            \
  2920. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
  2921.  
  2922. #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
  2923. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
  2924.  
  2925. #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)     \
  2926. __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
  2927.  
  2928. #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)              \
  2929. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char)        \
  2930. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char)      \
  2931. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int)         \
  2932. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int)       \
  2933. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int)   \
  2934. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
  2935. __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int)    \
  2936. __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int)  \
  2937. __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float)              \
  2938. __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double)             \
  2939. __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double)
  2940.  
  2941. #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
  2942. __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)        \
  2943. __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
  2944.  
  2945.  
  2946. #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun)                 \
  2947.                                                                        \
  2948. template <class T, class U>                                            \
  2949. inline __gmp_expr                                                      \
  2950. <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
  2951. fun(const __gmp_expr<T, U> &expr, unsigned long int l)                 \
  2952. {                                                                      \
  2953.   return __gmp_expr<T, __gmp_binary_expr                               \
  2954.     <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, l);        \
  2955. }
  2956.  
  2957.  
  2958. #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)         \
  2959.                                                                         \
  2960. template <class T, class U, class V, class W>                           \
  2961. inline type fun(const __gmp_expr<T, U> &expr1,                          \
  2962.         const __gmp_expr<V, W> &expr2)                          \
  2963. {                                                                       \
  2964.   typedef typename __gmp_resolve_expr<T, V>::value_type eval_type;      \
  2965.   typename __gmp_resolve_temp<eval_type, T, U>::temp_type temp1(expr1); \
  2966.   typename __gmp_resolve_temp<eval_type, V, W>::temp_type temp2(expr2); \
  2967.   return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp());            \
  2968. }
  2969.  
  2970. #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,   \
  2971.                         type2, bigtype)        \
  2972.                                                                    \
  2973. template <class T, class U>                                        \
  2974. inline type fun(const __gmp_expr<T, U> &expr, type2 t)             \
  2975. {                                                                  \
  2976.   typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr);      \
  2977.   return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
  2978. }                                                                  \
  2979.                                                                    \
  2980. template <class T, class U>                                        \
  2981. inline type fun(type2 t, const __gmp_expr<T, U> &expr)             \
  2982. {                                                                  \
  2983.   typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr);      \
  2984.   return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
  2985. }
  2986.  
  2987. #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2988. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
  2989.                     type2, signed long int)
  2990.  
  2991. #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2992. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
  2993.                     type2, unsigned long int)
  2994.  
  2995. #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
  2996. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
  2997.  
  2998. #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2)     \
  2999. __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
  3000.  
  3001. #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)              \
  3002. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char)        \
  3003. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char)      \
  3004. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int)         \
  3005. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int)       \
  3006. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int)   \
  3007. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
  3008. __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int)    \
  3009. __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int)  \
  3010. __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float)              \
  3011. __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double)             \
  3012. __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double)
  3013.  
  3014. #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
  3015. __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)        \
  3016. __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
  3017.  
  3018.  
  3019. // member operators
  3020.  
  3021. #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)                 \
  3022.                                                                              \
  3023. template <class T, class U>                                                  \
  3024. inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr)        \
  3025. {                                                                            \
  3026.   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr                  \
  3027.          <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
  3028.   return *this;                                                              \
  3029. }
  3030.  
  3031. #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,    \
  3032.                      type2, bigtype)         \
  3033.                                                                  \
  3034. inline type##_class & type##_class::fun(type2 t)                 \
  3035. {                                                                \
  3036.   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr      \
  3037.          <type##_class, bigtype, eval_fun> >(*this, t)); \
  3038.   return *this;                                                  \
  3039. }
  3040.  
  3041. #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  3042. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
  3043.                  type2, signed long int)
  3044.  
  3045. #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  3046. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
  3047.                  type2, unsigned long int)
  3048.  
  3049. #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
  3050. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
  3051.  
  3052. #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2)     \
  3053. __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
  3054.  
  3055. #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)              \
  3056. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char)        \
  3057. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char)      \
  3058. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int)         \
  3059. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int)       \
  3060. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int)   \
  3061. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
  3062. __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int)    \
  3063. __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int)  \
  3064. __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float)              \
  3065. __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double)             \
  3066. /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
  3067.  
  3068. #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
  3069. __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)        \
  3070. __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
  3071.  
  3072. #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  3073. __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
  3074.  
  3075. #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  3076. __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
  3077.  
  3078. #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
  3079. __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
  3080.  
  3081.  
  3082.  
  3083. #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun)  \
  3084.                                                                 \
  3085. inline type##_class & type##_class::fun(unsigned long int l)    \
  3086. {                                                               \
  3087.   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr     \
  3088.     <type##_class, unsigned long int, eval_fun> >(*this, l));   \
  3089.   return *this;                                                 \
  3090. }
  3091.  
  3092. #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  3093. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
  3094.  
  3095. #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  3096. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
  3097.  
  3098. #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
  3099. __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
  3100.  
  3101.  
  3102.  
  3103. #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
  3104.                                                              \
  3105. inline type##_class & type##_class::fun()                    \
  3106. {                                                            \
  3107.   eval_fun::eval(mp);                                        \
  3108.   return *this;                                              \
  3109. }                                                            \
  3110.                                                              \
  3111. inline type##_class type##_class::fun(int)                   \
  3112. {                                                            \
  3113.   type##_class temp(*this);                                  \
  3114.   eval_fun::eval(mp);                                        \
  3115.   return temp;                                               \
  3116. }
  3117.  
  3118. #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  3119. __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
  3120.  
  3121. #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  3122. __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
  3123.  
  3124. #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
  3125. __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
  3126.  
  3127.  
  3128.  
  3129. /**************** Arithmetic operators and functions ****************/
  3130.  
  3131. // non-member operators and functions
  3132.  
  3133. __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
  3134. __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
  3135. __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
  3136.  
  3137. __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
  3138. __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
  3139. __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
  3140. __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
  3141. __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
  3142. __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
  3143. __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
  3144. __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
  3145.  
  3146. __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
  3147. __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
  3148.  
  3149. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
  3150. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, __gmp_binary_not_equal)
  3151. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
  3152. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, __gmp_binary_less_equal)
  3153. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
  3154. __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, \
  3155.                                   __gmp_binary_greater_equal)
  3156.  
  3157. __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
  3158. __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
  3159. __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
  3160. __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
  3161. __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
  3162. __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
  3163.  
  3164. __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
  3165. __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
  3166.  
  3167. // member operators for mpz_class
  3168.  
  3169. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  3170. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  3171. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  3172. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  3173. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
  3174.  
  3175. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
  3176. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
  3177. __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
  3178.  
  3179. __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  3180. __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  3181.  
  3182. __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  3183. __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  3184.  
  3185. // member operators for mpq_class
  3186.  
  3187. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  3188. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  3189. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  3190. __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  3191.  
  3192. __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  3193. __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  3194.  
  3195. __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  3196. __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  3197.  
  3198. // member operators for mpf_class
  3199.  
  3200. __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
  3201. __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
  3202. __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
  3203. __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
  3204.  
  3205. __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
  3206. __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
  3207.  
  3208. __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
  3209. __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
  3210.  
  3211.  
  3212.  
  3213. /**************** Class wrapper for gmp_randstate_t ****************/
  3214.  
  3215. class __gmp_urandomb_value { };
  3216. class __gmp_urandomm_value { };
  3217.  
  3218. template <>
  3219. class __gmp_expr<mpz_t, __gmp_urandomb_value>
  3220. {
  3221. private:
  3222.   __gmp_randstate_struct *state;
  3223.   unsigned long int bits;
  3224. public:
  3225.   __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
  3226.   void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
  3227.   unsigned long int get_prec() const { return mpf_get_default_prec(); }
  3228. };
  3229.  
  3230. template <>
  3231. class __gmp_expr<mpz_t, __gmp_urandomm_value>
  3232. {
  3233. private:
  3234.   __gmp_randstate_struct *state;
  3235.   mpz_class range;
  3236. public:
  3237.   __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
  3238.   void eval(mpz_ptr z) const
  3239.   { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
  3240.   unsigned long int get_prec() const { return mpf_get_default_prec(); }
  3241. };
  3242.  
  3243. template <>
  3244. class __gmp_expr<mpf_t, __gmp_urandomb_value>
  3245. {
  3246. private:
  3247.   __gmp_randstate_struct *state;
  3248.   unsigned long int bits;
  3249. public:
  3250.   __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
  3251.   void eval(mpf_ptr f, unsigned long int prec) const
  3252.   { __gmp_rand_function::eval(f, state, (bits>0) ? get_prec() : prec); }
  3253.   unsigned long int get_prec() const
  3254.   {
  3255.     if (bits == 0)
  3256.       return mpf_get_default_prec();
  3257.     else
  3258.       return bits;
  3259.   }
  3260. };
  3261.  
  3262. extern "C" {
  3263.   typedef void __gmp_randinit_default_t (gmp_randstate_t);
  3264.   typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, unsigned long int);
  3265.   typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, unsigned long int);
  3266. }
  3267.  
  3268. class gmp_randclass
  3269. {
  3270. private:
  3271.   gmp_randstate_t state;
  3272.  
  3273.   // copy construction and assignment not allowed
  3274.   gmp_randclass(const gmp_randclass &);
  3275.   void operator=(const gmp_randclass &);
  3276. public:
  3277.   // constructors and destructor
  3278.   gmp_randclass(gmp_randalg_t alg, unsigned long int size)
  3279.   {
  3280.     switch (alg)
  3281.       {
  3282.       case GMP_RAND_ALG_LC: // no other cases for now
  3283.       default:
  3284.     gmp_randinit(state, alg, size);
  3285.     break;
  3286.       }
  3287.   }
  3288.  
  3289.   // gmp_randinit_default
  3290.   gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
  3291.  
  3292.   // gmp_randinit_lc_2exp
  3293.   gmp_randclass(__gmp_randinit_lc_2exp_t* f,
  3294.         mpz_class z, unsigned long int l1, unsigned long int l2)
  3295.   { f(state, z.get_mpz_t(), l1, l2); }
  3296.  
  3297.   // gmp_randinit_lc_2exp_size
  3298.   gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
  3299.         unsigned long int size)
  3300.   {
  3301.     if (f (state, size) == 0)
  3302.       throw std::length_error ("gmp_randinit_lc_2exp_size");
  3303.   }
  3304.  
  3305.   ~gmp_randclass() { gmp_randclear(state); }
  3306.  
  3307.   // initialize
  3308.   void seed(); // choose a random seed some way (?)
  3309.   void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
  3310.   void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
  3311.  
  3312.   // get random number
  3313.   __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(unsigned long int l)
  3314.   { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
  3315.   __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
  3316.   { return get_z_bits(z.get_ui()); }
  3317.  
  3318.   __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
  3319.   { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
  3320.  
  3321.   __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(unsigned long int prec = 0)
  3322.   { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
  3323. };
  3324.  
  3325.  
  3326. /**************** #undef all private macros ****************/
  3327.  
  3328. #undef __GMPP_DECLARE_COMPOUND_OPERATOR
  3329. #undef __GMPN_DECLARE_COMPOUND_OPERATOR
  3330. #undef __GMP_DECLARE_COMPOUND_OPERATOR
  3331. #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
  3332. #undef __GMP_DECLARE_INCREMENT_OPERATOR
  3333.  
  3334. #undef __GMPZQ_DEFINE_EXPR
  3335.  
  3336. #undef __GMP_DEFINE_UNARY_FUNCTION
  3337. #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
  3338.  
  3339. #undef __GMPP_DEFINE_BINARY_FUNCTION
  3340. #undef __GMPNN_DEFINE_BINARY_FUNCTION
  3341. #undef __GMPNS_DEFINE_BINARY_FUNCTION
  3342. #undef __GMPNU_DEFINE_BINARY_FUNCTION
  3343. #undef __GMPND_DEFINE_BINARY_FUNCTION
  3344. #undef __GMPNLD_DEFINE_BINARY_FUNCTION
  3345. #undef __GMPN_DEFINE_BINARY_FUNCTION
  3346. #undef __GMP_DEFINE_BINARY_FUNCTION
  3347.  
  3348. #undef __GMP_DEFINE_BINARY_FUNCTION_UI
  3349.  
  3350. #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
  3351. #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
  3352. #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
  3353. #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
  3354. #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
  3355. #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
  3356. #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
  3357. #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
  3358.  
  3359. #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
  3360. #undef __GMPZN_DEFINE_COMPOUND_OPERATOR
  3361. #undef __GMPZNN_DEFINE_COMPOUND_OPERATOR
  3362. #undef __GMPZNS_DEFINE_COMPOUND_OPERATOR
  3363. #undef __GMPZNU_DEFINE_COMPOUND_OPERATOR
  3364. #undef __GMPZND_DEFINE_COMPOUND_OPERATOR
  3365. #undef __GMPZNLD_DEFINE_COMPOUND_OPERATOR
  3366.  
  3367. #undef __GMPP_DEFINE_COMPOUND_OPERATOR
  3368. #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
  3369. #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
  3370. #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
  3371. #undef __GMPND_DEFINE_COMPOUND_OPERATOR
  3372. #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
  3373. #undef __GMPN_DEFINE_COMPOUND_OPERATOR
  3374. #undef __GMP_DEFINE_COMPOUND_OPERATOR
  3375.  
  3376. #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
  3377. #undef __GMPF_DEFINE_COMPOUND_OPERATOR
  3378.  
  3379. #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
  3380. #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
  3381. #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
  3382. #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
  3383.  
  3384. #undef __GMP_DEFINE_INCREMENT_OPERATOR
  3385. #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
  3386. #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
  3387. #undef __GMPF_DEFINE_INCREMENT_OPERATOR
  3388.  
  3389. #endif /* __GMP_PLUSPLUS__ */
  3390.